From ffadcff5d6fe0130758d5b76b85b7dbb9dcaa93e Mon Sep 17 00:00:00 2001 From: AOS Automation Release Team Date: Fri, 20 Jun 2025 11:12:09 +0000 Subject: [PATCH 001/115] Updating ose-ovn-kubernetes-container image to be consistent with ART for 4.20 Reconciling with https://github.com/openshift/ocp-build-data/tree/8f77fc475c95f9d98c348deb2feb88f5952d7357/images/ose-ovn-kubernetes.yml --- .ci-operator.yaml | 2 +- Dockerfile | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.ci-operator.yaml b/.ci-operator.yaml index 7c15f83e3e..461415cbc5 100644 --- a/.ci-operator.yaml +++ b/.ci-operator.yaml @@ -1,4 +1,4 @@ build_root_image: name: release namespace: openshift - tag: rhel-9-release-golang-1.23-openshift-4.19 + tag: rhel-9-release-golang-1.24-openshift-4.20 diff --git a/Dockerfile b/Dockerfile index 46ad2ccf60..74e10a832a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,7 +5,7 @@ # The standard name for this image is ovn-kube # Build RHEL-9 binaries -FROM registry.ci.openshift.org/ocp/builder:rhel-9-golang-1.23-openshift-4.19 AS builder +FROM registry.ci.openshift.org/ocp/builder:rhel-9-golang-1.24-openshift-4.20 AS builder WORKDIR /go/src/github.com/openshift/ovn-kubernetes COPY . . @@ -13,7 +13,7 @@ RUN cd go-controller; CGO_ENABLED=1 make RUN cd go-controller; CGO_ENABLED=0 make windows # Build RHEL-8 binaries (for upgrades from 4.12 and earlier) -FROM registry.ci.openshift.org/ocp/builder:rhel-8-golang-1.23-openshift-4.19 AS rhel8 +FROM registry.ci.openshift.org/ocp/builder:rhel-8-golang-1.24-openshift-4.20 AS rhel8 WORKDIR /go/src/github.com/openshift/ovn-kubernetes COPY . . RUN cd go-controller; CGO_ENABLED=1 make @@ -26,7 +26,7 @@ RUN cd go-controller; CGO_ENABLED=1 make # - creating directories required by ovn-kubernetes # - git commit number # - ovnkube.sh script -FROM registry.ci.openshift.org/ocp/4.19:ovn-kubernetes-base +FROM registry.ci.openshift.org/ocp/4.20:ovn-kubernetes-base USER root From c770ecdea77be4feb84e05a1450cdcad8ab6570a Mon Sep 17 00:00:00 2001 From: AOS Automation Release Team Date: Fri, 20 Jun 2025 11:26:29 +0000 Subject: [PATCH 002/115] Updating ovn-kubernetes-microshift-container image to be consistent with ART for 4.20 Reconciling with https://github.com/openshift/ocp-build-data/tree/8f77fc475c95f9d98c348deb2feb88f5952d7357/images/ovn-kubernetes-microshift.yml --- .ci-operator.yaml | 2 +- Dockerfile.microshift | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.ci-operator.yaml b/.ci-operator.yaml index 7c15f83e3e..461415cbc5 100644 --- a/.ci-operator.yaml +++ b/.ci-operator.yaml @@ -1,4 +1,4 @@ build_root_image: name: release namespace: openshift - tag: rhel-9-release-golang-1.23-openshift-4.19 + tag: rhel-9-release-golang-1.24-openshift-4.20 diff --git a/Dockerfile.microshift b/Dockerfile.microshift index 4846e332a4..e11933d1b4 100644 --- a/Dockerfile.microshift +++ b/Dockerfile.microshift @@ -12,7 +12,7 @@ # openvswitch-devel, openvswitch-ipsec, libpcap, iproute etc # ovn-kube-util, hybrid-overlay-node.exe, ovndbchecker and ovnkube-trace -FROM registry.ci.openshift.org/ocp/builder:rhel-9-golang-1.23-openshift-4.19 AS builder +FROM registry.ci.openshift.org/ocp/builder:rhel-9-golang-1.24-openshift-4.20 AS builder WORKDIR /go/src/github.com/openshift/ovn-kubernetes COPY . . @@ -20,7 +20,7 @@ COPY . . # build the binaries RUN cd go-controller; CGO_ENABLED=0 make -FROM registry.ci.openshift.org/ocp/4.19:ovn-kubernetes-base +FROM registry.ci.openshift.org/ocp/4.20:ovn-kubernetes-base USER root From 9a6e8e337c39a7185ad336dc50241f63c347729b Mon Sep 17 00:00:00 2001 From: Flavio Fernandes Date: Thu, 8 May 2025 21:04:04 +0000 Subject: [PATCH 003/115] ovnkube.sh: use node name as zone as default if ovn-ic If the `k8s.ovn.org/zone-name` label is not set on the node, the fallback logic now uses the node name as the zone when `ovn_enable_interconnect` is true. Otherwise, the zone defaults to "global" as before. Also updated the empty string check to use `-z`, which is more idiomatic in Bash. Signed-off-by: Flavio Fernandes --- dist/images/ovnkube.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/dist/images/ovnkube.sh b/dist/images/ovnkube.sh index 85b8eeab14..287b7a1f55 100755 --- a/dist/images/ovnkube.sh +++ b/dist/images/ovnkube.sh @@ -813,8 +813,12 @@ function memory_trim_on_compaction_supported { function get_node_zone() { zone=$(kubectl --subresource=status --server=${K8S_APISERVER} --token=${k8s_token} --certificate-authority=${K8S_CACERT} \ get node ${K8S_NODE} -o=jsonpath={'.metadata.labels.k8s\.ovn\.org/zone-name'}) - if [ "$zone" == "" ]; then - zone="global" + if [ -z "$zone" ]; then + if [[ ${ovn_enable_interconnect} == "true" ]]; then + zone="${K8S_NODE}" + else + zone="global" + fi fi echo "$zone" } From df487d267abf9cf225875a44622bf0be661e4204 Mon Sep 17 00:00:00 2001 From: Lei Huang Date: Tue, 15 Jul 2025 15:19:11 -0700 Subject: [PATCH 004/115] UDN: verify specific error messages in NAD rendering unit tests Update unit tests to check that the returned error contains the expected message, not just that an error occurred. This ensures the renderer fails for the right reasons, ensuring tests precisely validate failures. Signed-off-by: Lei Huang --- .../template/net-attach-def-template.go | 8 +- .../template/net-attach-def-template_test.go | 113 ++++++++++-------- go-controller/pkg/config/errors.go | 104 ++++++++++++++++ go-controller/pkg/config/utils.go | 13 +- go-controller/pkg/util/multi_network.go | 5 +- go-controller/pkg/util/multi_network_test.go | 24 ++-- go-controller/pkg/util/util.go | 8 ++ 7 files changed, 204 insertions(+), 71 deletions(-) create mode 100644 go-controller/pkg/config/errors.go diff --git a/go-controller/pkg/clustermanager/userdefinednetwork/template/net-attach-def-template.go b/go-controller/pkg/clustermanager/userdefinednetwork/template/net-attach-def-template.go index 0b3aa61194..02c7912e85 100644 --- a/go-controller/pkg/clustermanager/userdefinednetwork/template/net-attach-def-template.go +++ b/go-controller/pkg/clustermanager/userdefinednetwork/template/net-attach-def-template.go @@ -113,7 +113,7 @@ func validateTopology(spec SpecGetter) error { if spec.GetTopology() == userdefinednetworkv1.NetworkTopologyLayer3 && spec.GetLayer3() == nil || spec.GetTopology() == userdefinednetworkv1.NetworkTopologyLayer2 && spec.GetLayer2() == nil || spec.GetTopology() == userdefinednetworkv1.NetworkTopologyLocalnet && spec.GetLocalnet() == nil { - return fmt.Errorf("topology %[1]s is specified but %[1]s config is nil", spec.GetTopology()) + return config.NewTopologyConfigMismatchError(string(spec.GetTopology())) } return nil } @@ -142,10 +142,10 @@ func renderCNINetworkConfig(networkName, nadName string, spec SpecGetter) (map[s return nil, err } if ipamEnabled(cfg.IPAM) && len(cfg.Subnets) == 0 { - return nil, fmt.Errorf("subnets is required with ipam.mode is Enabled or unset") + return nil, config.NewSubnetsRequiredError() } if !ipamEnabled(cfg.IPAM) && len(cfg.Subnets) > 0 { - return nil, fmt.Errorf("subnets must be unset when ipam.mode is Disabled") + return nil, config.NewSubnetsMustBeUnsetError() } netConfSpec.Role = strings.ToLower(string(cfg.Role)) @@ -235,7 +235,7 @@ func validateIPAM(ipam *userdefinednetworkv1.IPAMConfig) error { return nil } if ipam.Lifecycle == userdefinednetworkv1.IPAMLifecyclePersistent && !ipamEnabled(ipam) { - return fmt.Errorf("lifecycle Persistent is only supported when ipam.mode is Enabled") + return config.NewIPAMLifecycleNotSupportedError() } return nil } diff --git a/go-controller/pkg/clustermanager/userdefinednetwork/template/net-attach-def-template_test.go b/go-controller/pkg/clustermanager/userdefinednetwork/template/net-attach-def-template_test.go index ab0593e210..c02109bf0e 100644 --- a/go-controller/pkg/clustermanager/userdefinednetwork/template/net-attach-def-template_test.go +++ b/go-controller/pkg/clustermanager/userdefinednetwork/template/net-attach-def-template_test.go @@ -9,16 +9,24 @@ import ( "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/config" udnv1 "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/crd/userdefinednetwork/v1" + "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/util" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" ) var _ = Describe("NetAttachDefTemplate", func() { + + // before each test, set the IPv4Mode and IPv6Mode to true + BeforeEach(func() { + config.IPv4Mode = true + config.IPv6Mode = true + }) + DescribeTable("should fail to render NAD spec given", - func(spec *udnv1.UserDefinedNetworkSpec) { + func(spec *udnv1.UserDefinedNetworkSpec, expectedError string) { _, err := RenderNADSpec("foo", "bar", spec) - Expect(err).To(HaveOccurred()) + Expect(err).To(MatchError(ContainSubstring(expectedError))) }, Entry("invalid layer2 subnets", &udnv1.UserDefinedNetworkSpec{ @@ -27,6 +35,7 @@ var _ = Describe("NetAttachDefTemplate", func() { Subnets: udnv1.DualStackCIDRs{"abc"}, }, }, + config.NewCIDRNotProperlyFormattedError("abc").Error(), ), Entry("invalid layer3 cluster-subnet", &udnv1.UserDefinedNetworkSpec{ @@ -35,6 +44,7 @@ var _ = Describe("NetAttachDefTemplate", func() { Subnets: []udnv1.Layer3Subnet{{CIDR: "!", HostSubnet: 16}}, }, }, + config.NewInvalidCIDRAddressError().Error(), ), Entry("invalid layer3 host-subnet mask", &udnv1.UserDefinedNetworkSpec{ @@ -45,6 +55,7 @@ var _ = Describe("NetAttachDefTemplate", func() { }, }, }, + config.NewHostSubnetMaskError(24, 24).Error(), // -1 is not a valid host subnet mask, it's converted to 24 ), Entry("layer3 host-subnet mask is smaller then cluster-subnet mask", &udnv1.UserDefinedNetworkSpec{ @@ -55,6 +66,7 @@ var _ = Describe("NetAttachDefTemplate", func() { }, }, }, + config.NewHostSubnetMaskError(16, 24).Error(), ), Entry("layer3 host-subnet mask equal to cluster-subnet mask", &udnv1.UserDefinedNetworkSpec{ @@ -65,16 +77,7 @@ var _ = Describe("NetAttachDefTemplate", func() { }, }, }, - ), - Entry("layer3 host-subnet mask is smaller then cluster-subnet mask", - &udnv1.UserDefinedNetworkSpec{ - Topology: udnv1.NetworkTopologyLayer3, - Layer3: &udnv1.Layer3Config{ - Subnets: []udnv1.Layer3Subnet{ - {CIDR: "10.10.0.0/16", HostSubnet: 8}, - }, - }, - }, + config.NewHostSubnetMaskError(24, 24).Error(), ), Entry("invalid layer3 host-subnet; IPv4 mask is bigger then 32", &udnv1.UserDefinedNetworkSpec{ @@ -85,102 +88,98 @@ var _ = Describe("NetAttachDefTemplate", func() { }, }, }, + config.NewInvalidIPv4HostSubnetError().Error(), ), - Entry("invalid join subnets", + Entry("invalid layer2 join subnets", &udnv1.UserDefinedNetworkSpec{ Topology: udnv1.NetworkTopologyLayer2, Layer2: &udnv1.Layer2Config{ Role: udnv1.NetworkRolePrimary, + Subnets: udnv1.DualStackCIDRs{"10.10.0.0/24"}, JoinSubnets: udnv1.DualStackCIDRs{"abc"}, }, }, + config.NewCIDRNotProperlyFormattedError("abc").Error(), ), - Entry("invalid dual-stack join subnets, invalid IPv4 CIDR", + Entry("invalid layer2 dual-stack join subnets, invalid IPv4 CIDR", &udnv1.UserDefinedNetworkSpec{ Topology: udnv1.NetworkTopologyLayer2, Layer2: &udnv1.Layer2Config{ Role: udnv1.NetworkRolePrimary, - JoinSubnets: udnv1.DualStackCIDRs{"!", "fd50::0/125"}, + Subnets: udnv1.DualStackCIDRs{"10.10.0.0/24"}, + JoinSubnets: udnv1.DualStackCIDRs{"fd50::0/125", "!"}, }, }, + config.NewCIDRNotProperlyFormattedError("!").Error(), ), - Entry("invalid dual-stack join subnets, invalid IPv6 CIDR", + Entry("invalid layer2 dual-stack join subnets, invalid IPv6 CIDR", &udnv1.UserDefinedNetworkSpec{ Topology: udnv1.NetworkTopologyLayer2, Layer2: &udnv1.Layer2Config{ Role: udnv1.NetworkRolePrimary, + Subnets: udnv1.DualStackCIDRs{"10.10.0.0/24"}, JoinSubnets: udnv1.DualStackCIDRs{"10.10.0.0/24", "!"}, }, }, + config.NewCIDRNotProperlyFormattedError("!").Error(), ), - Entry("invalid dual-stack join subnets, multiple valid IPv4 CIDRs", - &udnv1.UserDefinedNetworkSpec{ - Topology: udnv1.NetworkTopologyLayer2, - Layer2: &udnv1.Layer2Config{ - Role: udnv1.NetworkRolePrimary, - JoinSubnets: udnv1.DualStackCIDRs{"10.10.0.0/24", "10.20.0.0/24", "10.30.0.0/24"}, - }, - }, - ), - Entry("invalid dual-stack join subnets, multiple valid IPv6 CIDRs", - &udnv1.UserDefinedNetworkSpec{ - Topology: udnv1.NetworkTopologyLayer2, - Layer2: &udnv1.Layer2Config{ - Role: udnv1.NetworkRolePrimary, - JoinSubnets: udnv1.DualStackCIDRs{"fd40::0/125", "fd10::0/125", "fd50::0/125"}, - }, - }, - ), - Entry("invalid dual-stack join subnets, multiple valid IPv4 & IPv6 CIDRs", - &udnv1.UserDefinedNetworkSpec{ - Topology: udnv1.NetworkTopologyLayer2, - Layer2: &udnv1.Layer2Config{ - Role: udnv1.NetworkRolePrimary, - JoinSubnets: udnv1.DualStackCIDRs{"fd40::0/125", "10.10.0.0/24", "fd50::0/125", "10.20.0.0/24"}, - }, - }, - ), + // The validation for max number of subnets is moved to the CRD validation, + // no need to test it here. Entry("invalid join subnets, overlapping with cluster-default join-subnet, IPv4", &udnv1.UserDefinedNetworkSpec{ Topology: udnv1.NetworkTopologyLayer2, Layer2: &udnv1.Layer2Config{ Role: udnv1.NetworkRolePrimary, + Subnets: udnv1.DualStackCIDRs{"10.10.0.0/24"}, JoinSubnets: udnv1.DualStackCIDRs{"100.64.10.0/24"}, }, }, + config.NewSubnetOverlapError( + config.ConfigSubnet{SubnetType: config.UserDefinedJoinSubnet, Subnet: util.MustParseCIDR("100.64.10.0/24")}, + config.ConfigSubnet{SubnetType: config.ConfigSubnetJoin, Subnet: util.MustParseCIDR("100.64.0.0/16")}).Error(), ), Entry("invalid join subnets, overlapping with cluster-default join-subnet, IPv6", &udnv1.UserDefinedNetworkSpec{ Topology: udnv1.NetworkTopologyLayer2, Layer2: &udnv1.Layer2Config{ Role: udnv1.NetworkRolePrimary, + Subnets: udnv1.DualStackCIDRs{"10.10.0.0/24"}, JoinSubnets: udnv1.DualStackCIDRs{"fd98::4/127"}, }, }, + config.NewSubnetOverlapError( + config.ConfigSubnet{SubnetType: config.UserDefinedJoinSubnet, Subnet: util.MustParseCIDR("fd98::4/127")}, + config.ConfigSubnet{SubnetType: config.ConfigSubnetJoin, Subnet: util.MustParseCIDR("fd98::/64")}).Error(), ), Entry("invalid join subnets, overlapping with cluster-default join-subnet, dual-stack", &udnv1.UserDefinedNetworkSpec{ Topology: udnv1.NetworkTopologyLayer2, Layer2: &udnv1.Layer2Config{ Role: udnv1.NetworkRolePrimary, + Subnets: udnv1.DualStackCIDRs{"10.10.0.0/24"}, JoinSubnets: udnv1.DualStackCIDRs{"100.64.10.0/24", "fd98::4/127"}, }, }, + config.NewSubnetOverlapError( + config.ConfigSubnet{SubnetType: config.UserDefinedJoinSubnet, Subnet: util.MustParseCIDR("100.64.10.0/24")}, + config.ConfigSubnet{SubnetType: config.ConfigSubnetJoin, Subnet: util.MustParseCIDR("100.64.0.0/16")}).Error(), ), ) DescribeTable("should fail to render NAD manifest, given", - func(obj client.Object) { + func(obj client.Object, expectedError string) { _, err := RenderNetAttachDefManifest(obj, "test") - Expect(err).To(HaveOccurred()) + Expect(err).To(MatchError(ContainSubstring(expectedError))) }, Entry("UDN, invalid topology: topology layer2 & layer3 config", &udnv1.UserDefinedNetwork{Spec: udnv1.UserDefinedNetworkSpec{ Topology: udnv1.NetworkTopologyLayer2, Layer3: &udnv1.Layer3Config{}}}, + config.NewTopologyConfigMismatchError(string(udnv1.NetworkTopologyLayer2)).Error(), ), Entry("UDN, invalid topology: topology layer3 & layer2 config", &udnv1.UserDefinedNetwork{Spec: udnv1.UserDefinedNetworkSpec{ Topology: udnv1.NetworkTopologyLayer3, Layer2: &udnv1.Layer2Config{}}}, + config.NewTopologyConfigMismatchError(string(udnv1.NetworkTopologyLayer3)).Error(), ), Entry("UDN, invalid IPAM config: IPAM lifecycle & disabled ipam mode", &udnv1.UserDefinedNetwork{Spec: udnv1.UserDefinedNetworkSpec{ @@ -194,6 +193,7 @@ var _ = Describe("NetAttachDefTemplate", func() { }, }, }}, + config.NewIPAMLifecycleNotSupportedError().Error(), ), Entry("UDN, invalid IPAM config: IPAM enabled & no subnet", &udnv1.UserDefinedNetwork{Spec: udnv1.UserDefinedNetworkSpec{ @@ -206,6 +206,7 @@ var _ = Describe("NetAttachDefTemplate", func() { }, }, }}, + config.NewSubnetsRequiredError().Error(), ), Entry("UDN, invalid IPAM config: IPAM disabled & subnet", &udnv1.UserDefinedNetwork{Spec: udnv1.UserDefinedNetworkSpec{ @@ -218,39 +219,57 @@ var _ = Describe("NetAttachDefTemplate", func() { }, }, }}, + config.NewSubnetsMustBeUnsetError().Error(), ), Entry("CUDN, invalid topology: topology layer2 & layer3 config", &udnv1.ClusterUserDefinedNetwork{Spec: udnv1.ClusterUserDefinedNetworkSpec{Network: udnv1.NetworkSpec{ Topology: udnv1.NetworkTopologyLayer2, Layer3: &udnv1.Layer3Config{}}}}, + config.NewTopologyConfigMismatchError(string(udnv1.NetworkTopologyLayer2)).Error(), ), Entry("CUDN, invalid topology: topology layer2 & localnet config", &udnv1.ClusterUserDefinedNetwork{Spec: udnv1.ClusterUserDefinedNetworkSpec{Network: udnv1.NetworkSpec{ Topology: udnv1.NetworkTopologyLayer2, Localnet: &udnv1.LocalnetConfig{}}}}, + config.NewTopologyConfigMismatchError(string(udnv1.NetworkTopologyLayer2)).Error(), ), Entry("CUDN, invalid topology: topology layer3 & layer2 config", &udnv1.ClusterUserDefinedNetwork{Spec: udnv1.ClusterUserDefinedNetworkSpec{Network: udnv1.NetworkSpec{ Topology: udnv1.NetworkTopologyLayer3, Layer2: &udnv1.Layer2Config{}}}}, + config.NewTopologyConfigMismatchError(string(udnv1.NetworkTopologyLayer3)).Error(), ), Entry("CUDN, invalid topology: topology layer3 & localnet config", &udnv1.ClusterUserDefinedNetwork{Spec: udnv1.ClusterUserDefinedNetworkSpec{Network: udnv1.NetworkSpec{ Topology: udnv1.NetworkTopologyLayer3, Localnet: &udnv1.LocalnetConfig{}}}}, + config.NewTopologyConfigMismatchError(string(udnv1.NetworkTopologyLayer3)).Error(), ), Entry("CUDN, invalid topology: topology localnet & layer2 config", &udnv1.ClusterUserDefinedNetwork{Spec: udnv1.ClusterUserDefinedNetworkSpec{Network: udnv1.NetworkSpec{ Topology: udnv1.NetworkTopologyLocalnet, Layer2: &udnv1.Layer2Config{}}}}, + config.NewTopologyConfigMismatchError(string(udnv1.NetworkTopologyLocalnet)).Error(), ), Entry("CUDN, invalid topology: topology localnet & layer3 config", &udnv1.ClusterUserDefinedNetwork{Spec: udnv1.ClusterUserDefinedNetworkSpec{Network: udnv1.NetworkSpec{ Topology: udnv1.NetworkTopologyLocalnet, Layer3: &udnv1.Layer3Config{}}}}, + config.NewTopologyConfigMismatchError(string(udnv1.NetworkTopologyLocalnet)).Error(), + ), + Entry("CUDN, localnet: IPv4 excludeSubnets not in range of subnets", + &udnv1.ClusterUserDefinedNetwork{Spec: udnv1.ClusterUserDefinedNetworkSpec{Network: udnv1.NetworkSpec{ + Topology: udnv1.NetworkTopologyLocalnet, + Localnet: &udnv1.LocalnetConfig{Role: udnv1.NetworkRoleSecondary, PhysicalNetworkName: "localnet1", + Subnets: udnv1.DualStackCIDRs{"192.168.0.0/16", "2001:dbb::/64"}, + ExcludeSubnets: []udnv1.CIDR{"192.200.0.0/30"}, + }, + }}}, + config.NewExcludedSubnetNotContainedError("192.200.0.0/30").Error(), ), - Entry("CUDN, localnet: excludeSubnets not in range of subnets", + Entry("CUDN, localnet: IPv6 excludeSubnets not in range of subnets", &udnv1.ClusterUserDefinedNetwork{Spec: udnv1.ClusterUserDefinedNetworkSpec{Network: udnv1.NetworkSpec{ Topology: udnv1.NetworkTopologyLocalnet, Localnet: &udnv1.LocalnetConfig{Role: udnv1.NetworkRoleSecondary, PhysicalNetworkName: "localnet1", Subnets: udnv1.DualStackCIDRs{"192.168.0.0/16", "2001:dbb::/64"}, - ExcludeSubnets: []udnv1.CIDR{"192.200.0.0/30", "2001:aaa::/127", "192.300.0.1/32", "2001:bbb::1/120"}, + ExcludeSubnets: []udnv1.CIDR{"2001:aaa::/127"}, }, }}}, + config.NewExcludedSubnetNotContainedError("2001:aaa::/127").Error(), ), ) diff --git a/go-controller/pkg/config/errors.go b/go-controller/pkg/config/errors.go new file mode 100644 index 0000000000..9f634c2509 --- /dev/null +++ b/go-controller/pkg/config/errors.go @@ -0,0 +1,104 @@ +package config + +import "fmt" + +type ValidationErrorType string + +const ( + ErrCIDRNotProperlyFormatted ValidationErrorType = "CIDRNotProperlyFormatted" + ErrInvalidCIDRAddress ValidationErrorType = "InvalidCIDRAddress" + ErrHostSubnetMask ValidationErrorType = "HostSubnetMask" + ErrInvalidIPv4HostSubnet ValidationErrorType = "InvalidIPv4HostSubnet" + ErrSubnetOverlap ValidationErrorType = "SubnetOverlap" + ErrExcludedSubnetNotContained ValidationErrorType = "ExcludedSubnetNotContained" + ErrTopologyConfigMismatch ValidationErrorType = "TopologyConfigMismatch" + ErrIPAMLifecycleNotSupported ValidationErrorType = "IPAMLifecycleNotSupported" + ErrSubnetsRequired ValidationErrorType = "SubnetsRequired" + ErrSubnetsMustBeUnset ValidationErrorType = "SubnetsMustBeUnset" +) + +type ValidationError struct { + Type ValidationErrorType + Message string +} + +func (e *ValidationError) Error() string { + return e.Message +} + +// CIDR Validation Errors +func NewCIDRNotProperlyFormattedError(cidr string) *ValidationError { + return &ValidationError{ + Type: ErrCIDRNotProperlyFormatted, + Message: fmt.Sprintf("CIDR %q not properly formatted", cidr), + } +} + +func NewInvalidCIDRAddressError() *ValidationError { + return &ValidationError{ + Type: ErrInvalidCIDRAddress, + Message: "invalid CIDR address", + } +} + +// Subnet Validation Errors +func NewHostSubnetMaskError(hostSubnetLength, clusterSubnetLength int) *ValidationError { + return &ValidationError{ + Type: ErrHostSubnetMask, + Message: fmt.Sprintf("cannot use a host subnet length mask shorter than or equal to the cluster subnet mask. "+ + "host subnet length: %d, cluster subnet length: %d", hostSubnetLength, clusterSubnetLength), + } +} + +func NewInvalidIPv4HostSubnetError() *ValidationError { + return &ValidationError{ + Type: ErrInvalidIPv4HostSubnet, + Message: "invalid host subnet, IPv4 subnet must be < 32", + } +} + +func NewSubnetOverlapError(a, b ConfigSubnet) *ValidationError { + return &ValidationError{ + Type: ErrSubnetOverlap, + Message: fmt.Sprintf("%s %q overlaps %s %q", + a.SubnetType, a.Subnet.String(), + b.SubnetType, b.Subnet.String()), + } +} + +func NewExcludedSubnetNotContainedError(excludeSubnet interface{}) *ValidationError { + return &ValidationError{ + Type: ErrExcludedSubnetNotContained, + Message: fmt.Sprintf("the provided network subnets do not contain excluded subnets %v", excludeSubnet), + } +} + +// Topology Validation Errors +func NewTopologyConfigMismatchError(topology string) *ValidationError { + return &ValidationError{ + Type: ErrTopologyConfigMismatch, + Message: fmt.Sprintf("topology %[1]s is specified but %[1]s config is nil", topology), + } +} + +// IPAM Validation Errors +func NewIPAMLifecycleNotSupportedError() *ValidationError { + return &ValidationError{ + Type: ErrIPAMLifecycleNotSupported, + Message: "lifecycle Persistent is only supported when ipam.mode is Enabled", + } +} + +func NewSubnetsRequiredError() *ValidationError { + return &ValidationError{ + Type: ErrSubnetsRequired, + Message: "subnets is required with ipam.mode is Enabled or unset", + } +} + +func NewSubnetsMustBeUnsetError() *ValidationError { + return &ValidationError{ + Type: ErrSubnetsMustBeUnset, + Message: "subnets must be unset when ipam.mode is Disabled", + } +} diff --git a/go-controller/pkg/config/utils.go b/go-controller/pkg/config/utils.go index f0f0ff1a6b..20f4e0b35c 100644 --- a/go-controller/pkg/config/utils.go +++ b/go-controller/pkg/config/utils.go @@ -62,7 +62,7 @@ func ParseClusterSubnetEntriesWithDefaults(clusterSubnetCmd string, ipv4HostLeng splitClusterEntry := strings.Split(clusterEntry, "/") if len(splitClusterEntry) < 2 || len(splitClusterEntry) > 3 { - return nil, fmt.Errorf("CIDR %q not properly formatted", clusterEntry) + return nil, NewCIDRNotProperlyFormattedError(clusterEntry) } var err error @@ -78,7 +78,7 @@ func ParseClusterSubnetEntriesWithDefaults(clusterSubnetCmd string, ipv4HostLeng entryMaskLength, _ := parsedClusterEntry.CIDR.Mask.Size() if len(splitClusterEntry) == 3 { if !hostLengthAllowed { - return nil, fmt.Errorf("CIDR %q not properly formatted", clusterEntry) + return nil, NewCIDRNotProperlyFormattedError(clusterEntry) } tmp, err := strconv.Atoi(splitClusterEntry[2]) if err != nil { @@ -100,12 +100,11 @@ func ParseClusterSubnetEntriesWithDefaults(clusterSubnetCmd string, ipv4HostLeng } if !ipv6 && parsedClusterEntry.HostSubnetLength > 32 { - return nil, fmt.Errorf("invalid host subnet, IPv4 subnet must be < 32") + return nil, NewInvalidIPv4HostSubnetError() } if parsedClusterEntry.HostSubnetLength <= entryMaskLength { - return nil, fmt.Errorf("cannot use a host subnet length mask shorter than or equal to the cluster subnet mask. "+ - "host subnet length: %d, cluster subnet length: %d", parsedClusterEntry.HostSubnetLength, entryMaskLength) + return nil, NewHostSubnetMaskError(parsedClusterEntry.HostSubnetLength, entryMaskLength) } } @@ -216,9 +215,7 @@ func (cs *ConfigSubnets) CheckForOverlaps() error { for j := 0; j < i; j++ { sj := cs.Subnets[j] if si.Subnet.Contains(sj.Subnet.IP) || sj.Subnet.Contains(si.Subnet.IP) { - return fmt.Errorf("illegal network configuration: %s %q overlaps %s %q", - si.SubnetType, si.Subnet.String(), - sj.SubnetType, sj.Subnet.String()) + return NewSubnetOverlapError(si, sj) } } } diff --git a/go-controller/pkg/util/multi_network.go b/go-controller/pkg/util/multi_network.go index fd91edd3be..367531fb6e 100644 --- a/go-controller/pkg/util/multi_network.go +++ b/go-controller/pkg/util/multi_network.go @@ -1000,8 +1000,7 @@ func parseSubnets(subnetsString, excludeSubnetsString, topology string) ([]confi } } if !found { - return nil, nil, fmt.Errorf("the provided network subnets %v do not contain exluded subnets %v", - subnets, excludeSubnet.CIDR) + return nil, nil, config.NewExcludedSubnetNotContainedError(excludeSubnet.CIDR) } excludeIPNets = append(excludeIPNets, excludeSubnet.CIDR) } @@ -1258,7 +1257,7 @@ func subnetOverlapCheck(netconf *ovncnitypes.NetConf) error { } err = allSubnets.CheckForOverlaps() if err != nil { - return fmt.Errorf("pod or join subnet overlaps with already configured internal subnets: %v", err) + return fmt.Errorf("pod or join subnet overlaps with already configured internal subnets: %w", err) } return nil diff --git a/go-controller/pkg/util/multi_network_test.go b/go-controller/pkg/util/multi_network_test.go index daaaf920a5..8bdfcb3be9 100644 --- a/go-controller/pkg/util/multi_network_test.go +++ b/go-controller/pkg/util/multi_network_test.go @@ -1088,8 +1088,9 @@ func TestSubnetOverlapCheck(t *testing.T) { "netAttachDefName": "ns1/nad1" } `, - expectedError: fmt.Errorf("invalid subnet configuration: pod or join subnet overlaps with already configured internal subnets: " + - "illegal network configuration: user defined subnet \"10.129.0.0/16\" overlaps cluster subnet \"10.128.0.0/14\""), + expectedError: config.NewSubnetOverlapError( + config.ConfigSubnet{SubnetType: config.UserDefinedSubnets, Subnet: MustParseCIDR("10.129.0.0/16")}, + config.ConfigSubnet{SubnetType: config.ConfigSubnetCluster, Subnet: cidr4}), }, { desc: "return error when IPv4 join subnet in net-attach-def overlaps other subnets", @@ -1104,8 +1105,9 @@ func TestSubnetOverlapCheck(t *testing.T) { "netAttachDefName": "ns1/nad1" } `, - expectedError: fmt.Errorf("invalid subnet configuration: pod or join subnet overlaps with already configured internal subnets: " + - "illegal network configuration: user defined join subnet \"100.64.0.0/24\" overlaps built-in join subnet \"100.64.0.0/16\""), + expectedError: config.NewSubnetOverlapError( + config.ConfigSubnet{SubnetType: config.UserDefinedJoinSubnet, Subnet: MustParseCIDR("100.64.0.0/24")}, + config.ConfigSubnet{SubnetType: config.ConfigSubnetJoin, Subnet: MustParseCIDR(config.Gateway.V4JoinSubnet)}), }, { desc: "return error when IPv6 POD subnet in net-attach-def overlaps other subnets", @@ -1120,8 +1122,10 @@ func TestSubnetOverlapCheck(t *testing.T) { "netAttachDefName": "ns1/nad1" } `, - expectedError: fmt.Errorf("invalid subnet configuration: pod or join subnet overlaps with already configured internal subnets: " + - "illegal network configuration: user defined subnet \"fe01::/24\" overlaps service subnet \"fe01::/16\""), + expectedError: config.NewSubnetOverlapError( + config.ConfigSubnet{SubnetType: config.UserDefinedSubnets, Subnet: MustParseCIDR("fe01::/24")}, + config.ConfigSubnet{SubnetType: config.ConfigSubnetService, Subnet: svcCidr6}, + ), }, { desc: "return error when IPv6 join subnet in net-attach-def overlaps other subnets", @@ -1136,8 +1140,10 @@ func TestSubnetOverlapCheck(t *testing.T) { "netAttachDefName": "ns1/nad1" } `, - expectedError: fmt.Errorf("invalid subnet configuration: pod or join subnet overlaps with already configured internal subnets: " + - "illegal network configuration: user defined join subnet \"fd69::/112\" overlaps masquerade subnet \"fd69::/125\""), + expectedError: config.NewSubnetOverlapError( + config.ConfigSubnet{SubnetType: config.UserDefinedJoinSubnet, Subnet: MustParseCIDR("fd69::/112")}, + config.ConfigSubnet{SubnetType: config.ConfigSubnetMasquerade, Subnet: MustParseCIDR(config.Gateway.V6MasqueradeSubnet)}, + ), }, { desc: "excluded subnet should not be considered for overlap check", @@ -1177,7 +1183,7 @@ func TestSubnetOverlapCheck(t *testing.T) { }) if test.expectedError != nil { _, err := ParseNADInfo(networkAttachmentDefinition) - g.Expect(err).To(gomega.MatchError(test.expectedError.Error())) + g.Expect(err).To(gomega.MatchError(gomega.ContainSubstring(test.expectedError.Error()))) } else { _, err := ParseNADInfo(networkAttachmentDefinition) g.Expect(err).NotTo(gomega.HaveOccurred()) diff --git a/go-controller/pkg/util/util.go b/go-controller/pkg/util/util.go index cdcface465..4455de04c9 100644 --- a/go-controller/pkg/util/util.go +++ b/go-controller/pkg/util/util.go @@ -671,3 +671,11 @@ func GetMirroredEndpointSlices(controller, sourceName, namespace string, endpoin } return mirroredEndpointSlices, nil } + +func MustParseCIDR(cidr string) *net.IPNet { + _, ipNet, err := net.ParseCIDR(cidr) + if err != nil { + panic(fmt.Sprintf("failed to parse CIDR %q: %v", cidr, err)) + } + return ipNet +} From 410550fbb05be947ca8b5ad44dc73c3d2141d2ac Mon Sep 17 00:00:00 2001 From: Surya Seetharaman Date: Fri, 21 Mar 2025 08:52:58 +0100 Subject: [PATCH 005/115] Remove support for receiving advertised routes on nodes Today when default network or UDN networks are advertised using RAs the nodes also learn the routes of other nodes' pod subnets in the cluster. Example snippet of exposing a UDN network on non-vrflite usecase: root@ovn-worker2:/# ip r show table 1048 default via 172.18.0.1 dev breth0 mtu 1400 10.96.0.0/16 via 169.254.0.4 dev breth0 mtu 1400 10.244.0.0/24 nhid 39 via 172.18.0.4 dev breth0 proto bgp metric 20 10.244.2.0/24 nhid 40 via 172.18.0.3 dev breth0 proto bgp metric 20 103.103.0.0/24 nhid 39 via 172.18.0.4 dev breth0 proto bgp metric 20 103.103.1.0/24 nhid 40 via 172.18.0.3 dev breth0 proto bgp metric 20 169.254.0.3 via 203.203.1.1 dev ovn-k8s-mp12 169.254.0.34 dev ovn-k8s-mp12 mtu 1400 172.26.0.0/16 nhid 41 via 172.18.0.5 dev breth0 proto bgp metric 20 203.203.0.0/24 nhid 39 via 172.18.0.4 dev breth0 proto bgp metric 20 203.203.0.0/16 via 203.203.1.1 dev ovn-k8s-mp12 203.203.1.0/24 dev ovn-k8s-mp12 proto kernel scope link src 203.203.1.2 local 203.203.1.2 dev ovn-k8s-mp12 proto kernel scope host src 203.203.1.2 broadcast 203.203.1.255 dev ovn-k8s-mp12 proto kernel scope link src 203.203.1.2 203.203.2.0/24 nhid 40 via 172.18.0.3 dev breth0 proto bgp metric 20 root@ovn-worker2:/# ip r show table 1046 default via 172.18.0.1 dev breth0 mtu 1400 10.96.0.0/16 via 169.254.0.4 dev breth0 mtu 1400 10.244.0.0/24 nhid 39 via 172.18.0.4 dev breth0 proto bgp metric 20 10.244.2.0/24 nhid 40 via 172.18.0.3 dev breth0 proto bgp metric 20 103.103.0.0/24 nhid 39 via 172.18.0.4 dev breth0 proto bgp metric 20 103.103.0.0/16 via 103.103.2.1 dev ovn-k8s-mp11 103.103.1.0/24 nhid 40 via 172.18.0.3 dev breth0 proto bgp metric 20 103.103.2.0/24 dev ovn-k8s-mp11 proto kernel scope link src 103.103.2.2 local 103.103.2.2 dev ovn-k8s-mp11 proto kernel scope host src 103.103.2.2 broadcast 103.103.2.255 dev ovn-k8s-mp11 proto kernel scope link src 103.103.2.2 169.254.0.3 via 103.103.2.1 dev ovn-k8s-mp11 169.254.0.32 dev ovn-k8s-mp11 mtu 1400 172.26.0.0/16 nhid 41 via 172.18.0.5 dev breth0 proto bgp metric 20 203.203.0.0/24 nhid 39 via 172.18.0.4 dev breth0 proto bgp metric 20 203.203.2.0/24 nhid 40 via 172.18.0.3 dev breth0 proto bgp metric 20 root@ovn-worker2:/# this happens because we import routes from the default VRF: prefixes: - 103.103.0.0/24 - 2014:100:200::/64 - 2016:100:200::/64 - 203.203.0.0/24 - asn: 64512 imports: - vrf: default vrf: mp11-udn-vrf - asn: 64512 imports: - vrf: default vrf: mp12-udn-vrf nodeSelector: matchLabels: kubernetes.io/hostname: ovn-worker raw: {} root@ovn-worker2:/# ip r default via 172.18.0.1 dev breth0 mtu 1400 10.96.0.0/16 via 169.254.0.4 dev breth0 mtu 1400 10.244.0.0/24 nhid 39 via 172.18.0.4 dev breth0 proto bgp metric 20 10.244.2.0/24 nhid 40 via 172.18.0.3 dev breth0 proto bgp metric 20 103.103.0.0/24 nhid 39 via 172.18.0.4 dev breth0 proto bgp metric 20 103.103.1.0/24 nhid 40 via 172.18.0.3 dev breth0 proto bgp metric 20 169.254.0.3 via 203.203.1.1 dev ovn-k8s-mp12 169.254.0.34 dev ovn-k8s-mp12 mtu 1400 172.26.0.0/16 nhid 41 via 172.18.0.5 dev breth0 proto bgp metric 20 203.203.0.0/24 nhid 39 via 172.18.0.4 dev breth0 proto bgp metric 20 203.203.0.0/16 via 203.203.1.1 dev ovn-k8s-mp12 203.203.1.0/24 dev ovn-k8s-mp12 proto kernel scope link src 203.203.1.2 local 203.203.1.2 dev ovn-k8s-mp12 proto kernel scope host src 203.203.1.2 broadcast 203.203.1.255 dev ovn-k8s-mp12 proto kernel scope link src 203.203.1.2 203.203.2.0/24 nhid 40 via 172.18.0.3 dev breth0 proto bgp metric 20 which directly breaks UDN isolation. In this commit we are going to remove the support for receiving routes. So advertising routes will only advertise routes and we will no longer make the nodes receive these routes. However in the future when we support overlay-mode with BGP, we will need to re-add these routes and design a better isolation model with UDNs within the cluster if that is desired. Signed-off-by: Surya Seetharaman --- .../routeadvertisements/controller.go | 36 ++---------- .../routeadvertisements/controller_test.go | 55 ++++--------------- 2 files changed, 17 insertions(+), 74 deletions(-) diff --git a/go-controller/pkg/clustermanager/routeadvertisements/controller.go b/go-controller/pkg/clustermanager/routeadvertisements/controller.go index 18fb3dbaae..774a5341f3 100644 --- a/go-controller/pkg/clustermanager/routeadvertisements/controller.go +++ b/go-controller/pkg/clustermanager/routeadvertisements/controller.go @@ -593,14 +593,13 @@ func (c *Controller) generateFRRConfiguration( matchedNetworks sets.Set[string], ) (*frrtypes.FRRConfiguration, error) { routers := []frrtypes.Router{} - advertisements := sets.New(ra.Spec.Advertisements...) // go over the source routers for i, router := range source.Spec.BGP.Routers { targetVRF := ra.Spec.TargetVRF var matchedVRF, matchedNetwork string - var receivePrefixes, advertisePrefixes []string + var advertisePrefixes []string // We will use the router if: // - the router VRF matches the target VRF @@ -608,33 +607,25 @@ func (c *Controller) generateFRRConfiguration( // Prepare each scenario with a switch statement and check after that switch { case targetVRF == "auto" && router.VRF == "": - // match on default network/VRF, advertise node prefixes and receive - // any prefix of default network. + // match on default network/VRF, advertise node prefixes matchedVRF = "" matchedNetwork = types.DefaultNetworkName advertisePrefixes = selectedNetworks.hostNetworkSubnets[matchedNetwork] - receivePrefixes = selectedNetworks.networkSubnets[matchedNetwork] case targetVRF == "auto": - // match router.VRF to network.VRF, advertise node prefixes and - // receive any prefix of the matched network + // match router.VRF to network.VRF, advertise node prefixes matchedVRF = router.VRF matchedNetwork = selectedNetworks.networkVRFs[matchedVRF] advertisePrefixes = selectedNetworks.hostNetworkSubnets[matchedNetwork] - receivePrefixes = selectedNetworks.networkSubnets[matchedNetwork] case targetVRF == "": - // match on default network/VRF, advertise node prefixes and - // receive any prefix of selected networks + // match on default network/VRF, advertise node prefixes matchedVRF = "" matchedNetwork = types.DefaultNetworkName advertisePrefixes = selectedNetworks.hostSubnets - receivePrefixes = selectedNetworks.subnets default: - // match router.VRF to network.VRF, advertise node prefixes and - // receive any prefix of selected networks + // match router.VRF to network.VRF, advertise node prefixes matchedVRF = targetVRF matchedNetwork = selectedNetworks.networkVRFs[matchedVRF] advertisePrefixes = selectedNetworks.hostSubnets - receivePrefixes = selectedNetworks.subnets } if matchedVRF != router.VRF || len(advertisePrefixes) == 0 { // either this router VRF does not match the target VRF or we don't @@ -669,7 +660,6 @@ func (c *Controller) generateFRRConfiguration( isIPV6 := utilnet.IsIPv6String(neighbor.Address) advertisePrefixes := util.MatchAllIPNetsStringFamily(isIPV6, advertisePrefixes) - receivePrefixes := util.MatchAllIPNetsStringFamily(isIPV6, receivePrefixes) if len(advertisePrefixes) == 0 { continue } @@ -680,22 +670,6 @@ func (c *Controller) generateFRRConfiguration( Prefixes: advertisePrefixes, }, } - neighbor.ToReceive = frrtypes.Receive{ - Allowed: frrtypes.AllowedInPrefixes{ - Mode: frrtypes.AllowRestricted, - }, - } - if advertisements.Has(ratypes.PodNetwork) { - for _, prefix := range receivePrefixes { - neighbor.ToReceive.Allowed.Prefixes = append(neighbor.ToReceive.Allowed.Prefixes, - frrtypes.PrefixSelector{ - Prefix: prefix, - LE: selectedNetworks.prefixLength[prefix], - GE: selectedNetworks.prefixLength[prefix], - }, - ) - } - } targetRouter.Neighbors = append(targetRouter.Neighbors, neighbor) } if len(targetRouter.Neighbors) == 0 { diff --git a/go-controller/pkg/clustermanager/routeadvertisements/controller_test.go b/go-controller/pkg/clustermanager/routeadvertisements/controller_test.go index 305418425c..cf8d58729f 100644 --- a/go-controller/pkg/clustermanager/routeadvertisements/controller_test.go +++ b/go-controller/pkg/clustermanager/routeadvertisements/controller_test.go @@ -152,7 +152,6 @@ type testNeighbor struct { ASN uint32 Address string DisableMP *bool - Receive []string Advertise []string } @@ -161,11 +160,6 @@ func (tn testNeighbor) Neighbor() frrapi.Neighbor { ASN: tn.ASN, Address: tn.Address, DisableMP: true, - ToReceive: frrapi.Receive{ - Allowed: frrapi.AllowedInPrefixes{ - Mode: frrapi.AllowRestricted, - }, - }, ToAdvertise: frrapi.Advertise{ Allowed: frrapi.AllowedOutPrefixes{ Mode: frrapi.AllowRestricted, @@ -176,31 +170,6 @@ func (tn testNeighbor) Neighbor() frrapi.Neighbor { if tn.DisableMP != nil { n.DisableMP = *tn.DisableMP } - for _, receive := range tn.Receive { - sep := strings.LastIndex(receive, "/") - if sep == -1 { - continue - } - if isLayer2 := strings.Count(receive, "/") == 1; isLayer2 { - n.ToReceive.Allowed.Prefixes = append(n.ToReceive.Allowed.Prefixes, - frrapi.PrefixSelector{ - Prefix: receive, - }, - ) - continue - } - - first := receive[:sep] - last := receive[sep+1:] - len := ovntest.MustAtoi(last) - n.ToReceive.Allowed.Prefixes = append(n.ToReceive.Allowed.Prefixes, - frrapi.PrefixSelector{ - Prefix: first, - GE: uint32(len), - LE: uint32(len), - }, - ) - } return n } @@ -433,7 +402,7 @@ func TestController_reconcile(t *testing.T) { NodeSelector: map[string]string{"kubernetes.io/hostname": "node"}, Routers: []*testRouter{ {ASN: 1, Prefixes: []string{"1.0.1.1/32", "1.1.0.0/24"}, Neighbors: []*testNeighbor{ - {ASN: 1, Address: "1.0.0.100", Advertise: []string{"1.0.1.1/32", "1.1.0.0/24"}, Receive: []string{"1.1.0.0/16/24"}}, + {ASN: 1, Address: "1.0.0.100", Advertise: []string{"1.0.1.1/32", "1.1.0.0/24"}}, }}, }}, }, @@ -465,8 +434,8 @@ func TestController_reconcile(t *testing.T) { NodeSelector: map[string]string{"kubernetes.io/hostname": "node"}, Routers: []*testRouter{ {ASN: 1, Prefixes: []string{"1.0.1.1/32", "1.1.0.0/24", "fd01::/64", "fd03::ffff:100:101/128"}, Neighbors: []*testNeighbor{ - {ASN: 1, Address: "1.0.0.100", Advertise: []string{"1.0.1.1/32", "1.1.0.0/24"}, Receive: []string{"1.1.0.0/16/24"}}, - {ASN: 1, Address: "fd02::ffff:100:64", Advertise: []string{"fd01::/64", "fd03::ffff:100:101/128"}, Receive: []string{"fd01::/48/64"}}, + {ASN: 1, Address: "1.0.0.100", Advertise: []string{"1.0.1.1/32", "1.1.0.0/24"}}, + {ASN: 1, Address: "fd02::ffff:100:64", Advertise: []string{"fd01::/64", "fd03::ffff:100:101/128"}}, }}, }}, }, @@ -503,7 +472,7 @@ func TestController_reconcile(t *testing.T) { NodeSelector: map[string]string{"kubernetes.io/hostname": "node"}, Routers: []*testRouter{ {ASN: 1, Prefixes: []string{"1.2.0.0/24", "1.3.0.0/24", "1.4.0.0/16", "1.5.0.0/16"}, Imports: []string{"black", "blue", "green", "red"}, Neighbors: []*testNeighbor{ - {ASN: 1, Address: "1.0.0.100", Advertise: []string{"1.2.0.0/24", "1.3.0.0/24", "1.4.0.0/16", "1.5.0.0/16"}, Receive: []string{"1.2.0.0/16/24", "1.3.0.0/16/24", "1.4.0.0/16", "1.5.0.0/16"}}, + {ASN: 1, Address: "1.0.0.100", Advertise: []string{"1.2.0.0/24", "1.3.0.0/24", "1.4.0.0/16", "1.5.0.0/16"}}, }}, {ASN: 1, VRF: "black", Imports: []string{"default"}}, {ASN: 1, VRF: "blue", Imports: []string{"default"}}, @@ -636,7 +605,7 @@ func TestController_reconcile(t *testing.T) { NodeSelector: map[string]string{"kubernetes.io/hostname": "node"}, Routers: []*testRouter{ {ASN: 1, Prefixes: []string{"1.0.1.1/32", "1.1.0.0/24"}, Neighbors: []*testNeighbor{ - {ASN: 1, Address: "1.0.0.100", Advertise: []string{"1.0.1.1/32", "1.1.0.0/24"}, Receive: []string{"1.1.0.0/16/24"}}, + {ASN: 1, Address: "1.0.0.100", Advertise: []string{"1.0.1.1/32", "1.1.0.0/24"}}, }}, }, }, @@ -744,13 +713,13 @@ func TestController_reconcile(t *testing.T) { NodeSelector: map[string]string{"kubernetes.io/hostname": "node1"}, Routers: []*testRouter{ {ASN: 1, Prefixes: []string{"1.1.1.0/24"}, Neighbors: []*testNeighbor{ - {ASN: 1, Address: "1.0.0.100", Advertise: []string{"1.1.1.0/24"}, Receive: []string{"1.1.0.0/16/24"}}, + {ASN: 1, Address: "1.0.0.100", Advertise: []string{"1.1.1.0/24"}}, }}, {ASN: 1, VRF: "red", Prefixes: []string{"1.2.1.0/24"}, Neighbors: []*testNeighbor{ - {ASN: 1, Address: "1.0.0.100", Advertise: []string{"1.2.1.0/24"}, Receive: []string{"1.2.0.0/16/24"}}, + {ASN: 1, Address: "1.0.0.100", Advertise: []string{"1.2.1.0/24"}}, }}, {ASN: 1, VRF: "green", Prefixes: []string{"1.4.0.0/16"}, Neighbors: []*testNeighbor{ - {ASN: 1, Address: "1.0.0.100", Advertise: []string{"1.4.0.0/16"}, Receive: []string{"1.4.0.0/16"}}, + {ASN: 1, Address: "1.0.0.100", Advertise: []string{"1.4.0.0/16"}}, }}, }, }, @@ -760,7 +729,7 @@ func TestController_reconcile(t *testing.T) { NodeSelector: map[string]string{"kubernetes.io/hostname": "node2"}, Routers: []*testRouter{ {ASN: 1, Prefixes: []string{"1.1.2.0/24"}, Neighbors: []*testNeighbor{ - {ASN: 1, Address: "1.0.0.100", Advertise: []string{"1.1.2.0/24"}, Receive: []string{"1.1.0.0/16/24"}}, + {ASN: 1, Address: "1.0.0.100", Advertise: []string{"1.1.2.0/24"}}, }}, }, }, @@ -770,10 +739,10 @@ func TestController_reconcile(t *testing.T) { NodeSelector: map[string]string{"kubernetes.io/hostname": "node2"}, Routers: []*testRouter{ {ASN: 1, VRF: "red", Prefixes: []string{"1.2.2.0/24"}, Neighbors: []*testNeighbor{ - {ASN: 1, Address: "1.0.0.100", Advertise: []string{"1.2.2.0/24"}, Receive: []string{"1.2.0.0/16/24"}}, + {ASN: 1, Address: "1.0.0.100", Advertise: []string{"1.2.2.0/24"}}, }}, {ASN: 1, VRF: "green", Prefixes: []string{"1.4.0.0/16"}, Neighbors: []*testNeighbor{ - {ASN: 1, Address: "1.0.0.100", Advertise: []string{"1.4.0.0/16"}, Receive: []string{"1.4.0.0/16"}}, + {ASN: 1, Address: "1.0.0.100", Advertise: []string{"1.4.0.0/16"}}, }}, }, }, @@ -799,7 +768,7 @@ func TestController_reconcile(t *testing.T) { NodeSelector: map[string]string{"kubernetes.io/hostname": "node"}, Routers: []*testRouter{ {ASN: 1, Prefixes: []string{"1.0.1.1/32", "1.1.0.0/24"}, Neighbors: []*testNeighbor{ - {ASN: 1, Address: "1.0.0.100", Advertise: []string{"1.0.1.1/32", "1.1.0.0/24"}, Receive: []string{"1.1.0.0/16/24"}}, + {ASN: 1, Address: "1.0.0.100", Advertise: []string{"1.0.1.1/32", "1.1.0.0/24"}}, }}, }, }, From ea1b6a018e6d537ac3460474ce7e517fddd312dd Mon Sep 17 00:00:00 2001 From: Surya Seetharaman Date: Tue, 22 Jul 2025 14:14:07 +0200 Subject: [PATCH 006/115] Don't use match as a criteria for isEquivalentMatch This is a temporary commit - we need a proper followup. Please see https://github.com/ovn-kubernetes/ovn-kubernetes/issues/5407 for details. As of today all NATs created by OVN-Kubernetes are unique using the existing 5 tuple algo in IsEquivalentNAT - uuid, type of snat, logicalIP, logicalPort, externalIP, externalIDs. So its OK to get rid of match. But its not the correct way to fix this - in future we might have two NATs with all other fields except match being the same. Signed-off-by: Surya Seetharaman --- go-controller/pkg/libovsdb/ops/router.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/go-controller/pkg/libovsdb/ops/router.go b/go-controller/pkg/libovsdb/ops/router.go index 18b3931a1f..27e8e38d48 100644 --- a/go-controller/pkg/libovsdb/ops/router.go +++ b/go-controller/pkg/libovsdb/ops/router.go @@ -1035,7 +1035,7 @@ func BuildDNATAndSNATWithMatch( // isEquivalentNAT checks if the `searched` NAT is equivalent to `existing`. // Returns true if the UUID is set in `searched` and matches the UUID of `existing`. // Otherwise, perform the following checks: -// - Compare the Type and Match fields. +// - Compare the Type. // - Compare ExternalIP if it is set in `searched`. // - Compare LogicalIP if the Type in `searched` is SNAT. // - Compare LogicalPort if it is set in `searched`. @@ -1050,10 +1050,6 @@ func isEquivalentNAT(existing *nbdb.NAT, searched *nbdb.NAT) bool { return false } - if searched.Match != existing.Match { - return false - } - // Compare externalIP if it's not empty. if searched.ExternalIP != "" && searched.ExternalIP != existing.ExternalIP { return false From 15adf65d17ffa28a64fce27bbc73491b0800330c Mon Sep 17 00:00:00 2001 From: Surya Seetharaman Date: Thu, 19 Jun 2025 19:12:30 +0200 Subject: [PATCH 007/115] Advertised networks: SNAT Traffic to nodeIP This PR is adding SNAT for advertised UDNs and CDN if the destination of the traffic is towards other nodes in the cluster. This is a design change for BGP from before (where pod->node was not SNATed and podIP was preserved). For normal UDNs we have 2 SNATs: L3 UDN SNATs: 1) this cSNAT is added to ovn_cluster_router for LGW egress traffic and SGW KAPI/DNS traffic: _uuid : 5485a25f-7a83-4dc0-840c-bbfbd0784aad allowed_ext_ips : [] exempted_ext_ips : [] external_ids : {"k8s.ovn.org/network"=cluster_udn_tenant-green-network, "k8s.ovn.org/topology"=layer3} external_ip : "169.254.0.38" external_mac : [] external_port_range : "32768-60999" gateway_port : [] logical_ip : "203.203.0.0/24" logical_port : rtos-cluster_udn_tenant.green.network_ovn-control-plane match : "eth.dst == 0a:58:cb:cb:00:02" options : {stateless="false"} priority : 0 type : snat 2) this SNAT is added to GR for SGW egress traffic: _uuid : d85fd65f-e3f3-4d52-95f9-5f88c925aa5a allowed_ext_ips : [] exempted_ext_ips : [] external_ids : {"k8s.ovn.org/network"=cluster_udn_tenant-green-network, "k8s.ovn.org/topology"=layer3} external_ip : "169.254.0.37" external_mac : [] external_port_range : "32768-60999" gateway_port : [] logical_ip : "203.203.0.0/16" logical_port : [] match : "" options : {stateless="false"} priority : 0 type : snat for L2, we have the following two SNATs both on GR: _uuid : a4b9942f-ec1a-42ca-81d9-3e4885ff2470 allowed_ext_ips : [] exempted_ext_ips : [] external_ids : {"k8s.ovn.org/network"=cluster_udn_tenant-blue-network, "k8s.ovn.org/topology"=layer2} external_ip : "169.254.0.36" external_mac : [] external_port_range : "32768-60999" gateway_port : [] logical_ip : "93.93.0.0/16" logical_port : rtoj-GR_cluster_udn_tenant.blue.network_ovn-control-plane match : "eth.dst == 0a:58:5d:5d:00:02" options : {stateless="false"} priority : 0 type : snat and _uuid : 24164866-da95-4b6f-9c65-8b16fa202758 allowed_ext_ips : [] exempted_ext_ips : [] external_ids : {"k8s.ovn.org/network"=cluster_udn_tenant-blue-network, "k8s.ovn.org/topology"=layer2} external_ip : "169.254.0.35" external_mac : [] external_port_range : "32768-60999" gateway_port : [] logical_ip : "93.93.0.0/16" logical_port : [] match : "outport == \"rtoe-GR_cluster_udn_tenant.blue.network_ovn-control-plane\"" options : {stateless="false"} priority : 0 type : snat now with advertised networks these will change to: _uuid : a4b9942f-ec1a-42ca-81d9-3e4885ff2470 allowed_ext_ips : [] exempted_ext_ips : [] external_ids : {"k8s.ovn.org/network"=cluster_udn_tenant-blue-network, "k8s.ovn.org/topology"=layer2} external_ip : "169.254.0.36" external_mac : [] external_port_range : "32768-60999" gateway_port : [] logical_ip : "93.93.0.0/16" logical_port : rtoj-GR_cluster_udn_tenant.blue.network_ovn-control-plane match : "eth.dst == 0a:58:5d:5d:00:02 && (ip4.dst == $a712973235162149816)" options : {stateless="false"} priority : 0 type : snat _uuid : 24164866-da95-4b6f-9c65-8b16fa202758 allowed_ext_ips : [] exempted_ext_ips : [] external_ids : {"k8s.ovn.org/network"=cluster_udn_tenant-blue-network, "k8s.ovn.org/topology"=layer2} external_ip : "169.254.0.35" external_mac : [] external_port_range : "32768-60999" gateway_port : [] logical_ip : "93.93.0.0/16" logical_port : [] match : "outport == \"rtoe-GR_cluster_udn_tenant.blue.network_ovn-control-plane\" && ip4.dst == $a712973235162149816" options : {stateless="false"} priority : 0 type : snat _uuid : d85fd65f-e3f3-4d52-95f9-5f88c925aa5a allowed_ext_ips : [] exempted_ext_ips : [] external_ids : {"k8s.ovn.org/network"=cluster_udn_tenant-green-network, "k8s.ovn.org/topology"=layer3} external_ip : "169.254.0.37" external_mac : [] external_port_range : "32768-60999" gateway_port : [] logical_ip : "203.203.0.0/16" logical_port : [] match : "ip4.dst == $a712973235162149816" options : {stateless="false"} priority : 0 type : snat _uuid : 5485a25f-7a83-4dc0-840c-bbfbd0784aad allowed_ext_ips : [] exempted_ext_ips : [] external_ids : {"k8s.ovn.org/network"=cluster_udn_tenant-green-network, "k8s.ovn.org/topology"=layer3} external_ip : "169.254.0.38" external_mac : [] external_port_range : "32768-60999" gateway_port : [] logical_ip : "203.203.0.0/24" logical_port : rtos-cluster_udn_tenant.green.network_ovn-control-plane match : "eth.dst == 0a:58:cb:cb:00:02 && (ip4.dst == $a712973235162149816)" options : {stateless="false"} priority : 0 type : snat so basically we add this extra match for destination IPs to SNAT to masqueradeIP for that UDN note: with this PR we will break hardware offload for assymmetry traffix for BGP L2 As for the CDN, we have 1 SNAT with no matches on GR and that is being changed to now have a cSNAT in case the default network is advertised. NOTE: In -ds flag mode, the per-pod SNAT will have this match set. NOTE2: For all deleteNAT scenarios we purposefully don't pass snat as a match criteria Signed-off-by: Surya Seetharaman Signed-off-by: Surya Seetharaman --- .../ovn/base_network_controller_secondary.go | 46 ++++++++--- go-controller/pkg/ovn/egressgw.go | 12 +-- go-controller/pkg/ovn/egressip.go | 22 ++++-- go-controller/pkg/ovn/gateway.go | 51 +++++++++++- go-controller/pkg/ovn/gateway_test.go | 32 ++++++++ go-controller/pkg/ovn/master_test.go | 42 +++++++--- go-controller/pkg/ovn/namespace.go | 40 +++++++++- go-controller/pkg/ovn/pods.go | 20 ++++- .../secondary_layer2_network_controller.go | 77 ++++++++----------- .../secondary_layer3_network_controller.go | 44 +++-------- go-controller/pkg/util/multi_network.go | 12 --- 11 files changed, 269 insertions(+), 129 deletions(-) diff --git a/go-controller/pkg/ovn/base_network_controller_secondary.go b/go-controller/pkg/ovn/base_network_controller_secondary.go index f9c6d0b18f..253524ff87 100644 --- a/go-controller/pkg/ovn/base_network_controller_secondary.go +++ b/go-controller/pkg/ovn/base_network_controller_secondary.go @@ -812,7 +812,7 @@ func (oc *BaseSecondaryNetworkController) allowPersistentIPs() bool { // buildUDNEgressSNAT is used to build the conditional SNAT required on L3 and L2 UDNs to // steer traffic correctly via mp0 when leaving OVN to the host -func (bsnc *BaseSecondaryNetworkController) buildUDNEgressSNAT(localPodSubnets []*net.IPNet, outputPort string) ([]*nbdb.NAT, error) { +func (bsnc *BaseSecondaryNetworkController) buildUDNEgressSNAT(localPodSubnets []*net.IPNet, outputPort string, isUDNAdvertised bool) ([]*nbdb.NAT, error) { if len(localPodSubnets) == 0 { return nil, nil // nothing to do } @@ -828,10 +828,11 @@ func (bsnc *BaseSecondaryNetworkController) buildUDNEgressSNAT(localPodSubnets [ types.TopologyExternalID: bsnc.TopologyType(), } for _, localPodSubnet := range localPodSubnets { + ipFamily := utilnet.IPv4 + masqIP, err = udn.AllocateV4MasqueradeIPs(networkID) if utilnet.IsIPv6CIDR(localPodSubnet) { masqIP, err = udn.AllocateV6MasqueradeIPs(networkID) - } else { - masqIP, err = udn.AllocateV4MasqueradeIPs(networkID) + ipFamily = utilnet.IPv6 } if err != nil { return nil, err @@ -839,12 +840,43 @@ func (bsnc *BaseSecondaryNetworkController) buildUDNEgressSNAT(localPodSubnets [ if masqIP == nil { return nil, fmt.Errorf("masquerade IP cannot be empty network %s (%d): %v", bsnc.GetNetworkName(), networkID, err) } - snats = append(snats, libovsdbops.BuildSNATWithMatch(&masqIP.ManagementPort.IP, localPodSubnet, outputPort, - extIDs, getMasqueradeManagementIPSNATMatch(dstMac.String()))) + if !isUDNAdvertised { + snats = append(snats, libovsdbops.BuildSNATWithMatch(&masqIP.ManagementPort.IP, localPodSubnet, outputPort, + extIDs, getMasqueradeManagementIPSNATMatch(dstMac.String()))) + } else { + // For advertised networks, we need to SNAT any traffic leaving the pods from these networks towards the node IPs + // in the cluster. In order to do such a conditional SNAT, we need an address set that contains the node IPs in the cluster. + // Given that egressIP feature already has an address set containing these nodeIPs owned by the default network controller, let's re-use it. + dbIDs := getEgressIPAddrSetDbIDs(NodeIPAddrSetName, types.DefaultNetworkName, DefaultNetworkControllerName) + addrSet, err := bsnc.addressSetFactory.GetAddressSet(dbIDs) + if err != nil { + return nil, fmt.Errorf("cannot ensure that addressSet %s exists: %w", NodeIPAddrSetName, err) + } + ipv4ClusterNodeIPAS, ipv6ClusterNodeIPAS := addrSet.GetASHashNames() + + snats = append(snats, libovsdbops.BuildSNATWithMatch(&masqIP.ManagementPort.IP, localPodSubnet, outputPort, + extIDs, fmt.Sprintf("%s && (%s)", getMasqueradeManagementIPSNATMatch(dstMac.String()), + getClusterNodesDestinationBasedSNATMatch(ipv4ClusterNodeIPAS, ipv6ClusterNodeIPAS, ipFamily)))) + } } return snats, nil } +func getMasqueradeManagementIPSNATMatch(dstMac string) string { + return fmt.Sprintf("eth.dst == %s", dstMac) +} + +// getClusterNodesDestinationBasedSNATMatch creates destination-based SNAT match for the specified IP family +func getClusterNodesDestinationBasedSNATMatch(ipv4ClusterNodeIPAS, ipv6ClusterNodeIPAS string, ipFamily utilnet.IPFamily) string { + var match string + if ipFamily == utilnet.IPv4 { + match = fmt.Sprintf("ip4.dst == $%s", ipv4ClusterNodeIPAS) + } else { + match = fmt.Sprintf("ip6.dst == $%s", ipv6ClusterNodeIPAS) + } + return match +} + func (bsnc *BaseSecondaryNetworkController) ensureDHCP(pod *corev1.Pod, podAnnotation *util.PodAnnotation, lsp *nbdb.LogicalSwitchPort) error { opts := []kubevirt.DHCPConfigsOpt{} @@ -867,10 +899,6 @@ func (bsnc *BaseSecondaryNetworkController) ensureDHCP(pod *corev1.Pod, podAnnot return kubevirt.EnsureDHCPOptionsForLSP(bsnc.controllerName, bsnc.nbClient, pod, podAnnotation.IPs, lsp, opts...) } -func getMasqueradeManagementIPSNATMatch(dstMac string) string { - return fmt.Sprintf("eth.dst == %s", dstMac) -} - func (bsnc *BaseSecondaryNetworkController) requireDHCP(pod *corev1.Pod) bool { // Configure DHCP only for kubevirt VMs layer2 primary udn with subnets return kubevirt.IsPodOwnedByVirtualMachine(pod) && diff --git a/go-controller/pkg/ovn/egressgw.go b/go-controller/pkg/ovn/egressgw.go index b607a3b253..d9d8610aba 100644 --- a/go-controller/pkg/ovn/egressgw.go +++ b/go-controller/pkg/ovn/egressgw.go @@ -589,7 +589,7 @@ func (oc *DefaultNetworkController) deletePodSNAT(nodeName string, extIPs, podIP return nil } // Default network does not set any matches in Pod SNAT - ops, err := deletePodSNATOps(oc.nbClient, nil, oc.GetNetworkScopedGWRouterName(nodeName), extIPs, podIPNets, "") + ops, err := deletePodSNATOps(oc.nbClient, nil, oc.GetNetworkScopedGWRouterName(nodeName), extIPs, podIPNets) if err != nil { return err } @@ -639,8 +639,8 @@ func getExternalIPsGR(watchFactory *factory.WatchFactory, nodeName string) ([]*n // deletePodSNATOps creates ovsdb operation that removes per pod SNAT rules towards the nodeIP that are applied to the GR where the pod resides // used when disableSNATMultipleGWs=true -func deletePodSNATOps(nbClient libovsdbclient.Client, ops []ovsdb.Operation, gwRouterName string, extIPs, podIPNets []*net.IPNet, match string) ([]ovsdb.Operation, error) { - nats, err := buildPodSNAT(extIPs, podIPNets, match) +func deletePodSNATOps(nbClient libovsdbclient.Client, ops []ovsdb.Operation, gwRouterName string, extIPs, podIPNets []*net.IPNet) ([]ovsdb.Operation, error) { + nats, err := buildPodSNAT(extIPs, podIPNets, "") // for delete, match is not needed - we try to cleanup all the SNATs that match the isEquivalentNAT predicate if err != nil { return nil, err } @@ -657,7 +657,7 @@ func deletePodSNATOps(nbClient libovsdbclient.Client, ops []ovsdb.Operation, gwR // addOrUpdatePodSNAT adds or updates per pod SNAT rules towards the nodeIP that are applied to the GR where the pod resides // used when disableSNATMultipleGWs=true func addOrUpdatePodSNAT(nbClient libovsdbclient.Client, gwRouterName string, extIPs, podIfAddrs []*net.IPNet) error { - ops, err := addOrUpdatePodSNATOps(nbClient, gwRouterName, extIPs, podIfAddrs, nil) + ops, err := addOrUpdatePodSNATOps(nbClient, gwRouterName, extIPs, podIfAddrs, "", nil) if err != nil { return err } @@ -670,9 +670,9 @@ func addOrUpdatePodSNAT(nbClient libovsdbclient.Client, gwRouterName string, ext // addOrUpdatePodSNATOps returns the operation that adds or updates per pod SNAT rules towards the nodeIP that are // applied to the GR where the pod resides // used when disableSNATMultipleGWs=true -func addOrUpdatePodSNATOps(nbClient libovsdbclient.Client, gwRouterName string, extIPs, podIfAddrs []*net.IPNet, ops []ovsdb.Operation) ([]ovsdb.Operation, error) { +func addOrUpdatePodSNATOps(nbClient libovsdbclient.Client, gwRouterName string, extIPs, podIfAddrs []*net.IPNet, snatMatch string, ops []ovsdb.Operation) ([]ovsdb.Operation, error) { gwRouter := &nbdb.LogicalRouter{Name: gwRouterName} - nats, err := buildPodSNAT(extIPs, podIfAddrs, "") + nats, err := buildPodSNAT(extIPs, podIfAddrs, snatMatch) if err != nil { return nil, err } diff --git a/go-controller/pkg/ovn/egressip.go b/go-controller/pkg/ovn/egressip.go index 5f50cefb95..ed018c0de3 100644 --- a/go-controller/pkg/ovn/egressip.go +++ b/go-controller/pkg/ovn/egressip.go @@ -249,7 +249,7 @@ func NewEIPController( // CASE 3.4: Both Namespace && Pod Selectors on Spec changed // } // -// NOTE: `Spec.EgressIPs“ updates for EIP object are not processed here, that is the job of cluster manager +// NOTE: `Spec.EgressIPs" updates for EIP object are not processed here, that is the job of cluster manager // // We only care about `Spec.NamespaceSelector`, `Spec.PodSelector` and `Status` field func (e *EgressIPController) reconcileEgressIP(old, new *egressipv1.EgressIP) (err error) { @@ -2594,9 +2594,21 @@ func (e *EgressIPController) addExternalGWPodSNATOps(ni util.NetInfo, ops []ovsd if err != nil { return nil, err } - ops, err = addOrUpdatePodSNATOps(e.nbClient, ni.GetNetworkScopedGWRouterName(pod.Spec.NodeName), extIPs, podIPs, ops) - if err != nil { - return nil, err + + // Handle each pod IP individually since each IP family needs its own SNAT match + for _, podIP := range podIPs { + ipFamily := utilnet.IPv4 + if utilnet.IsIPv6CIDR(podIP) { + ipFamily = utilnet.IPv6 + } + snatMatch, err := GetNetworkScopedClusterSubnetSNATMatch(e.nbClient, ni, pod.Spec.NodeName, util.IsPodNetworkAdvertisedAtNode(ni, pod.Spec.NodeName), ipFamily) + if err != nil { + return nil, fmt.Errorf("failed to get SNAT match for node %s for network %s: %w", pod.Spec.NodeName, ni.GetNetworkName(), err) + } + ops, err = addOrUpdatePodSNATOps(e.nbClient, ni.GetNetworkScopedGWRouterName(pod.Spec.NodeName), extIPs, []*net.IPNet{podIP}, snatMatch, ops) + if err != nil { + return nil, err + } } klog.V(5).Infof("Adding SNAT on %s since egress node managing %s/%s was the same: %s", pod.Spec.NodeName, pod.Namespace, pod.Name, status.Node) } @@ -2617,7 +2629,7 @@ func (e *EgressIPController) deleteExternalGWPodSNATOps(ni util.NetInfo, ops []o if err != nil { return nil, err } - ops, err = deletePodSNATOps(e.nbClient, ops, ni.GetNetworkScopedGWRouterName(pod.Spec.NodeName), extIPs, affectedIPs, "") + ops, err = deletePodSNATOps(e.nbClient, ops, ni.GetNetworkScopedGWRouterName(pod.Spec.NodeName), extIPs, affectedIPs) if err != nil { return nil, err } diff --git a/go-controller/pkg/ovn/gateway.go b/go-controller/pkg/ovn/gateway.go index a43adf5368..66bce44dfe 100644 --- a/go-controller/pkg/ovn/gateway.go +++ b/go-controller/pkg/ovn/gateway.go @@ -25,6 +25,7 @@ import ( "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/metrics" "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/nbdb" "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/node" + addressset "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/ovn/address_set" "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/ovn/gateway" "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/ovn/gatewayrouter" "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/types" @@ -42,7 +43,6 @@ type GatewayManager struct { nbClient libovsdbclient.Client netInfo util.NetInfo watchFactory *factory.WatchFactory - // Cluster wide Load_Balancer_Group UUID. // Includes all node switches and node gateway routers. clusterLoadBalancerGroupUUID string @@ -764,7 +764,9 @@ func (gw *GatewayManager) updateGWRouterNAT(nodeName string, clusterIPSubnet []* nats := make([]*nbdb.NAT, 0, len(clusterIPSubnet)) var nat *nbdb.NAT - if (!config.Gateway.DisableSNATMultipleGWs || gw.netInfo.IsPrimaryNetwork()) && !gw.isRoutingAdvertised(nodeName) { + // DisableSNATMultipleGWs is only applicable to cluster default network and not to user defined networks. + // For user defined networks, we always add SNAT rules regardless of whether the network is advertised or not. + if !config.Gateway.DisableSNATMultipleGWs || gw.netInfo.IsPrimaryNetwork() { // Default SNAT rules. DisableSNATMultipleGWs=false in LGW (traffic egresses via mp0) always. // We are not checking for gateway mode to be shared explicitly to reduce topology differences. for _, entry := range clusterIPSubnet { @@ -774,7 +776,17 @@ func (gw *GatewayManager) updateGWRouterNAT(nodeName string, clusterIPSubnet []* gw.gwRouterName, err) } - nat = libovsdbops.BuildSNATWithMatch(&externalIP[0], entry, "", extIDs, gw.netInfo.GetNetworkScopedClusterSubnetSNATMatch(nodeName)) + // Get the match for this specific subnet's IP family + ipFamily := utilnet.IPv4 + if utilnet.IsIPv6CIDR(entry) { + ipFamily = utilnet.IPv6 + } + snatMatch, err := GetNetworkScopedClusterSubnetSNATMatch(gw.nbClient, gw.netInfo, nodeName, gw.isRoutingAdvertised(nodeName), ipFamily) + if err != nil { + return fmt.Errorf("failed to get SNAT match for node %s for network %s: %w", nodeName, gw.netInfo.GetNetworkName(), err) + } + + nat = libovsdbops.BuildSNATWithMatch(&externalIP[0], entry, "", extIDs, snatMatch) nats = append(nats, nat) } err = libovsdbops.CreateOrUpdateNATs(gw.nbClient, gwRouter, nats...) @@ -784,7 +796,7 @@ func (gw *GatewayManager) updateGWRouterNAT(nodeName string, clusterIPSubnet []* } else { // ensure we do not have any leftover SNAT entries after an upgrade for _, logicalSubnet := range clusterIPSubnet { - nat = libovsdbops.BuildSNATWithMatch(nil, logicalSubnet, "", extIDs, gw.netInfo.GetNetworkScopedClusterSubnetSNATMatch(nodeName)) + nat = libovsdbops.BuildSNAT(nil, logicalSubnet, "", extIDs) nats = append(nats, nat) } err = libovsdbops.DeleteNATs(gw.nbClient, gwRouter, nats...) @@ -902,6 +914,37 @@ func (gw *GatewayManager) gatewayInit( return nil } +// GetNetworkScopedClusterSubnetSNATMatch returns the match for the SNAT rule for the cluster default network +// and the match for the SNAT rule for the L3/L2 user defined network. +// If the network is not advertised: +// - For Layer2 topology, the match is the output port of the GR to the join switch since in L2 there is only 1 router but two cSNATs. +// - For Layer3 topology, the match is empty. +// If the network is advertised: +// - For Layer2 topology, the match is the output port of the GR to the join switch and the destination must be a nodeIP in the cluster. +// - For Layer3 topology, the match is the destination must be a nodeIP in the cluster. +func GetNetworkScopedClusterSubnetSNATMatch(nbClient libovsdbclient.Client, netInfo util.NetInfo, nodeName string, isNetworkAdvertised bool, ipFamily utilnet.IPFamily) (string, error) { + if !isNetworkAdvertised { + if netInfo.TopologyType() != types.Layer2Topology { + return "", nil + } + return fmt.Sprintf("outport == %q", types.GWRouterToExtSwitchPrefix+netInfo.GetNetworkScopedGWRouterName(nodeName)), nil + } else { + // if the network is advertised, we need to ensure that the SNAT exists with the correct conditional destination match + dbIDs := getEgressIPAddrSetDbIDs(NodeIPAddrSetName, types.DefaultNetworkName, DefaultNetworkControllerName) + addressSetFactory := addressset.NewOvnAddressSetFactory(nbClient, config.IPv4Mode, config.IPv6Mode) + addrSet, err := addressSetFactory.GetAddressSet(dbIDs) + if err != nil { + return "", fmt.Errorf("cannot ensure that addressSet %s exists %v", NodeIPAddrSetName, err) + } + ipv4ClusterNodeIPAS, ipv6ClusterNodeIPAS := addrSet.GetASHashNames() + destinationMatch := getClusterNodesDestinationBasedSNATMatch(ipv4ClusterNodeIPAS, ipv6ClusterNodeIPAS, ipFamily) + if netInfo.TopologyType() != types.Layer2Topology { + return destinationMatch, nil + } + return fmt.Sprintf("outport == %q && (%s)", types.GWRouterToExtSwitchPrefix+netInfo.GetNetworkScopedGWRouterName(nodeName), destinationMatch), nil + } +} + // addExternalSwitch creates a switch connected to the external bridge and connects it to // the gateway router func (gw *GatewayManager) addExternalSwitch(prefix, interfaceID, gatewayRouter, macAddress, physNetworkName string, ipAddresses []*net.IPNet, vlanID *uint) error { diff --git a/go-controller/pkg/ovn/gateway_test.go b/go-controller/pkg/ovn/gateway_test.go index 61f89e831d..893d17ad09 100644 --- a/go-controller/pkg/ovn/gateway_test.go +++ b/go-controller/pkg/ovn/gateway_test.go @@ -65,6 +65,15 @@ func generateGatewayInitExpectedNB(testData []libovsdbtest.TestData, expectedOVN expectedNodeSwitch *nbdb.LogicalSwitch, nodeName string, clusterIPSubnets []*net.IPNet, hostSubnets []*net.IPNet, l3GatewayConfig *util.L3GatewayConfig, joinLRPIPs, defLRPIPs []*net.IPNet, skipSnat bool, nodeMgmtPortIP, gatewayMTU string) []libovsdbtest.TestData { + return generateGatewayInitExpectedNBWithPodNetworkAdvertised(testData, expectedOVNClusterRouter, expectedNodeSwitch, + nodeName, clusterIPSubnets, hostSubnets, l3GatewayConfig, joinLRPIPs, defLRPIPs, skipSnat, nodeMgmtPortIP, + gatewayMTU, false) // Default to no pod network advertised +} + +func generateGatewayInitExpectedNBWithPodNetworkAdvertised(testData []libovsdbtest.TestData, expectedOVNClusterRouter *nbdb.LogicalRouter, + expectedNodeSwitch *nbdb.LogicalSwitch, nodeName string, clusterIPSubnets []*net.IPNet, hostSubnets []*net.IPNet, + l3GatewayConfig *util.L3GatewayConfig, joinLRPIPs, defLRPIPs []*net.IPNet, skipSnat bool, nodeMgmtPortIP, + gatewayMTU string, isPodNetworkAdvertised bool) []libovsdbtest.TestData { GRName := "GR_" + nodeName gwSwitchPort := types.JoinSwitchToGWRouterPrefix + GRName @@ -214,6 +223,16 @@ func generateGatewayInitExpectedNB(testData []libovsdbtest.TestData, expectedOVN }, Networks: networks, }) + var egressNodeIPsASv4, egressNodeIPsASv6 *nbdb.AddressSet + if config.OVNKubernetesFeature.EnableEgressIP { + egressNodeIPsASv4, egressNodeIPsASv6 = buildEgressIPNodeAddressSets(physicalIPs) + if config.IPv4Mode { + testData = append(testData, egressNodeIPsASv4) + } + if config.IPv6Mode { + testData = append(testData, egressNodeIPsASv6) + } + } natUUIDs := make([]string, 0, len(clusterIPSubnets)) if !skipSnat { @@ -231,6 +250,19 @@ func generateGatewayInitExpectedNB(testData []libovsdbtest.TestData, expectedOVN if config.Gateway.Mode != config.GatewayModeDisabled { nat.ExternalPortRange = config.DefaultEphemeralPortRange } + if isPodNetworkAdvertised { + // IPv6 pod network + if utilnet.IsIPv6CIDR(subnet) { + if egressNodeIPsASv6 != nil { + nat.Match = fmt.Sprintf("ip6.dst == $%s", egressNodeIPsASv6.Name) + } + } else { + // IPv4 pod network + if egressNodeIPsASv4 != nil { + nat.Match = fmt.Sprintf("ip4.dst == $%s", egressNodeIPsASv4.Name) + } + } + } testData = append(testData, &nat) } } diff --git a/go-controller/pkg/ovn/master_test.go b/go-controller/pkg/ovn/master_test.go index b7b902f740..866b6309fa 100644 --- a/go-controller/pkg/ovn/master_test.go +++ b/go-controller/pkg/ovn/master_test.go @@ -963,6 +963,7 @@ var _ = ginkgo.Describe("Default network controller operations", func() { // Restore global default values before each testcase gomega.Expect(config.PrepareTestConfig()).To(gomega.Succeed()) fakeOvn = NewFakeOVN(true) + config.OVNKubernetesFeature.EnableEgressIP = true app = cli.NewApp() app.Name = "test" @@ -1043,6 +1044,19 @@ var _ = ginkgo.Describe("Default network controller operations", func() { l3GatewayConfig = node1.gatewayConfig(config.GatewayModeLocal, uint(vlanID)) err = util.SetL3GatewayConfig(nodeAnnotator, l3GatewayConfig) gomega.Expect(err).NotTo(gomega.HaveOccurred()) + if config.OVNKubernetesFeature.EnableEgressIP { + physicalIPs := []string{} + for _, ip := range l3GatewayConfig.IPAddresses { + physicalIPs = append(physicalIPs, ip.IP.String()) + } + egressNodeIPsASv4, egressNodeIPsASv6 := buildEgressIPNodeAddressSets(physicalIPs) + if config.IPv4Mode { + dbSetup.NBData = append(dbSetup.NBData, egressNodeIPsASv4) + } + if config.IPv6Mode { + dbSetup.NBData = append(dbSetup.NBData, egressNodeIPsASv6) + } + } err = util.UpdateNodeManagementPortMACAddresses(&testNode, nodeAnnotator, ovntest.MustParseMAC(node1.NodeMgmtPortMAC), types.DefaultNetworkName) gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -1249,6 +1263,7 @@ var _ = ginkgo.Describe("Default network controller operations", func() { "reconciles pod network SNATs from syncGateway", func(condition func(*DefaultNetworkController) error, expectedExtraNATs ...*nbdb.NAT) { app.Action = func(ctx *cli.Context) error { + // Initialize config from CLI flags (including --init-gateways) _, err := config.InitConfig(ctx, nil, nil) gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -1258,6 +1273,10 @@ var _ = ginkgo.Describe("Default network controller operations", func() { _, err = fakeClient.KubeClient.CoreV1().Pods(ns.Name).Create(context.TODO(), &pod, metav1.CreateOptions{}) gomega.Expect(err).NotTo(gomega.HaveOccurred()) + // generate specific test conditions (after base config is set) + err = condition(oc) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + // Let the real code run and ensure OVN database sync gomega.Expect(oc.WatchNodes()).To(gomega.Succeed()) @@ -1268,10 +1287,6 @@ var _ = ginkgo.Describe("Default network controller operations", func() { err = libovsdbops.CreateOrUpdateNATs(nbClient, GR, extraNats...) gomega.Expect(err).NotTo(gomega.HaveOccurred()) - // generate specific test conditions - err = condition(oc) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - // ensure the stale SNAT's are cleaned up gomega.Expect(oc.StartServiceController(wg, false)).To(gomega.Succeed()) subnet := ovntest.MustParseIPNet(node1.NodeSubnet) @@ -1281,19 +1296,23 @@ var _ = ginkgo.Describe("Default network controller operations", func() { err = oc.syncNodeGateway(testNode) gomega.Expect(err).NotTo(gomega.HaveOccurred()) - skipSnat := config.Gateway.DisableSNATMultipleGWs || oc.isPodNetworkAdvertisedAtNode(node1.Name) + skipSnat := config.Gateway.DisableSNATMultipleGWs && !oc.GetNetInfo().IsPrimaryNetwork() var clusterSubnets []*net.IPNet for _, clusterSubnet := range config.Default.ClusterSubnets { clusterSubnets = append(clusterSubnets, clusterSubnet.CIDR) } expectedNBDatabaseState = addNodeLogicalFlowsWithServiceController(nil, expectedOVNClusterRouter, expectedNodeSwitch, expectedClusterRouterPortGroup, expectedClusterPortGroup, &node1, oc.svcTemplateSupport) - expectedNBDatabaseState = generateGatewayInitExpectedNB(expectedNBDatabaseState, expectedOVNClusterRouter, - expectedNodeSwitch, node1.Name, clusterSubnets, []*net.IPNet{subnet}, l3GatewayConfig, - []*net.IPNet{classBIPAddress(node1.LrpIP)}, []*net.IPNet{classBIPAddress(node1.DrLrpIP)}, - skipSnat, node1.NodeMgmtPortIP, "1400") - - if oc.isPodNetworkAdvertisedAtNode(node1.Name) { + if !oc.isPodNetworkAdvertisedAtNode(node1.Name) { + expectedNBDatabaseState = generateGatewayInitExpectedNB(expectedNBDatabaseState, expectedOVNClusterRouter, + expectedNodeSwitch, node1.Name, clusterSubnets, []*net.IPNet{subnet}, l3GatewayConfig, + []*net.IPNet{classBIPAddress(node1.LrpIP)}, []*net.IPNet{classBIPAddress(node1.DrLrpIP)}, + skipSnat, node1.NodeMgmtPortIP, "1400") + } else { + expectedNBDatabaseState = generateGatewayInitExpectedNBWithPodNetworkAdvertised(expectedNBDatabaseState, expectedOVNClusterRouter, + expectedNodeSwitch, node1.Name, clusterSubnets, []*net.IPNet{subnet}, l3GatewayConfig, + []*net.IPNet{classBIPAddress(node1.LrpIP)}, []*net.IPNet{classBIPAddress(node1.DrLrpIP)}, + skipSnat, node1.NodeMgmtPortIP, "1400", true) addrSet, err := oc.addressSetFactory.GetAddressSet(GetAdvertisedNetworkSubnetsAddressSetDBIDs()) gomega.Expect(err).NotTo(gomega.HaveOccurred()) expectedNBDatabaseState = generateAdvertisedUDNIsolationExpectedNB(expectedNBDatabaseState, oc.GetNetworkName(), oc.GetNetworkID(), clusterSubnets, expectedNodeSwitch, addrSet) @@ -1353,6 +1372,7 @@ var _ = ginkgo.Describe("Default network controller operations", func() { "When pod network is advertised and DisableSNATMultipleGWs is false", func(oc *DefaultNetworkController) error { config.Gateway.DisableSNATMultipleGWs = false + config.OVNKubernetesFeature.EnableEgressIP = true mutableNetInfo := util.NewMutableNetInfo(oc.GetNetInfo()) mutableNetInfo.SetPodNetworkAdvertisedVRFs(map[string][]string{"node1": {"vrf"}}) return oc.Reconcile(mutableNetInfo) diff --git a/go-controller/pkg/ovn/namespace.go b/go-controller/pkg/ovn/namespace.go index 01f189228b..07282de4df 100644 --- a/go-controller/pkg/ovn/namespace.go +++ b/go-controller/pkg/ovn/namespace.go @@ -8,10 +8,12 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/klog/v2" + utilnet "k8s.io/utils/net" "github.com/ovn-kubernetes/libovsdb/ovsdb" "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/config" + libovsdbops "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/libovsdb/ops" "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/types" "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/util" utilerrors "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/util/errors" @@ -234,9 +236,41 @@ func (oc *DefaultNetworkController) updateNamespace(old, newer *corev1.Namespace if err != nil { errors = append(errors, err) } else { - if extIPs, err := getExternalIPsGR(oc.watchFactory, pod.Spec.NodeName); err != nil { - errors = append(errors, err) - } else if err = addOrUpdatePodSNAT(oc.nbClient, oc.GetNetworkScopedGWRouterName(pod.Spec.NodeName), extIPs, podAnnotation.IPs); err != nil { + // Helper function to handle the complex SNAT operations + handleSNATOps := func() error { + extIPs, err := getExternalIPsGR(oc.watchFactory, pod.Spec.NodeName) + if err != nil { + return err + } + + var ops []ovsdb.Operation + // Handle each pod IP individually since each IP family needs its own SNAT match + for _, podIP := range podAnnotation.IPs { + ipFamily := utilnet.IPv4 + if utilnet.IsIPv6CIDR(podIP) { + ipFamily = utilnet.IPv6 + } + snatMatch, err := GetNetworkScopedClusterSubnetSNATMatch(oc.nbClient, oc.GetNetInfo(), pod.Spec.NodeName, oc.isPodNetworkAdvertisedAtNode(pod.Spec.NodeName), ipFamily) + if err != nil { + return fmt.Errorf("failed to get SNAT match for node %s for network %s: %v", pod.Spec.NodeName, oc.GetNetworkName(), err) + } + ops, err = addOrUpdatePodSNATOps(oc.nbClient, oc.GetNetworkScopedGWRouterName(pod.Spec.NodeName), extIPs, []*net.IPNet{podIP}, snatMatch, ops) + if err != nil { + return err + } + } + + // Execute all operations in a single transaction + if len(ops) > 0 { + _, err = libovsdbops.TransactAndCheck(oc.nbClient, ops) + if err != nil { + return fmt.Errorf("failed to update SNAT for pod %s on router %s: %v", pod.Name, oc.GetNetworkScopedGWRouterName(pod.Spec.NodeName), err) + } + } + return nil + } + + if err := handleSNATOps(); err != nil { errors = append(errors, err) } } diff --git a/go-controller/pkg/ovn/pods.go b/go-controller/pkg/ovn/pods.go index 5c3478f3cb..0ad9442e3e 100644 --- a/go-controller/pkg/ovn/pods.go +++ b/go-controller/pkg/ovn/pods.go @@ -12,6 +12,7 @@ import ( corev1 "k8s.io/api/core/v1" ktypes "k8s.io/apimachinery/pkg/types" "k8s.io/klog/v2" + utilnet "k8s.io/utils/net" "github.com/ovn-kubernetes/libovsdb/ovsdb" @@ -310,13 +311,26 @@ func (oc *DefaultNetworkController) addLogicalPort(pod *corev1.Pod) (err error) if err != nil { return err } - } else if config.Gateway.DisableSNATMultipleGWs && !oc.isPodNetworkAdvertisedAtNode(pod.Spec.NodeName) { + } else if config.Gateway.DisableSNATMultipleGWs { // Add NAT rules to pods if disable SNAT is set and does not have // namespace annotations to go through external egress router if extIPs, err := getExternalIPsGR(oc.watchFactory, pod.Spec.NodeName); err != nil { return err - } else if ops, err = addOrUpdatePodSNATOps(oc.nbClient, oc.GetNetworkScopedGWRouterName(pod.Spec.NodeName), extIPs, podAnnotation.IPs, ops); err != nil { - return err + } else { + // Handle each pod IP individually since each IP family needs its own SNAT match + for _, podIP := range podAnnotation.IPs { + ipFamily := utilnet.IPv4 + if utilnet.IsIPv6CIDR(podIP) { + ipFamily = utilnet.IPv6 + } + snatMatch, err := GetNetworkScopedClusterSubnetSNATMatch(oc.nbClient, oc.GetNetInfo(), pod.Spec.NodeName, oc.isPodNetworkAdvertisedAtNode(pod.Spec.NodeName), ipFamily) + if err != nil { + return fmt.Errorf("failed to get SNAT match for node %s for network %s: %v", pod.Spec.NodeName, oc.GetNetworkName(), err) + } + if ops, err = addOrUpdatePodSNATOps(oc.nbClient, oc.GetNetworkScopedGWRouterName(pod.Spec.NodeName), extIPs, []*net.IPNet{podIP}, snatMatch, ops); err != nil { + return err + } + } } } diff --git a/go-controller/pkg/ovn/secondary_layer2_network_controller.go b/go-controller/pkg/ovn/secondary_layer2_network_controller.go index 7ce63fc278..dacf37d090 100644 --- a/go-controller/pkg/ovn/secondary_layer2_network_controller.go +++ b/go-controller/pkg/ovn/secondary_layer2_network_controller.go @@ -575,36 +575,40 @@ func (oc *SecondaryLayer2NetworkController) addUpdateLocalNodeEvent(node *corev1 gwManager := oc.gatewayManagerForNode(node.Name) oc.gatewayManagers.Store(node.Name, gwManager) - gwConfig, err := oc.nodeGatewayConfig(node) - if err != nil { - errs = append(errs, err) - oc.gatewaysFailed.Store(node.Name, true) - } else { + err := func() error { + gwConfig, err := oc.nodeGatewayConfig(node) + if err != nil { + return err + } if err := gwManager.SyncGateway( node, gwConfig, ); err != nil { - errs = append(errs, err) - oc.gatewaysFailed.Store(node.Name, true) - } else { - if !util.IsPodNetworkAdvertisedAtNode(oc, node.Name) { - err = oc.addUDNClusterSubnetEgressSNAT(gwConfig.hostSubnets, gwManager.gwRouterName) - if err == nil && util.IsRouteAdvertisementsEnabled() { - err = oc.deleteAdvertisedNetworkIsolation(node.Name) - } - } else { - err = oc.deleteUDNClusterSubnetEgressSNAT(gwConfig.hostSubnets, gwManager.gwRouterName) - if err == nil { - err = oc.addAdvertisedNetworkIsolation(node.Name) + return err + } + isUDNAdvertised := util.IsPodNetworkAdvertisedAtNode(oc, node.Name) + err = oc.addOrUpdateUDNClusterSubnetEgressSNAT(gwConfig.hostSubnets, gwManager.gwRouterName, isUDNAdvertised) + if err != nil { + return err + } + if !isUDNAdvertised { + if util.IsRouteAdvertisementsEnabled() { + if err = oc.deleteAdvertisedNetworkIsolation(node.Name); err != nil { + return err } } - if err != nil { - errs = append(errs, err) - oc.gatewaysFailed.Store(node.Name, true) - } else { - oc.gatewaysFailed.Delete(node.Name) + } else { + if err = oc.addAdvertisedNetworkIsolation(node.Name); err != nil { + return err } } + oc.gatewaysFailed.Delete(node.Name) + return nil + }() + + if err != nil { + errs = append(errs, err) + oc.gatewaysFailed.Store(node.Name, true) } } @@ -741,7 +745,8 @@ func (oc *SecondaryLayer2NetworkController) deleteNodeEvent(node *corev1.Node) e return nil } -// addUDNClusterSubnetEgressSNAT adds the SNAT on each node's GR in L2 networks +// addOrUpdateUDNClusterSubnetEgressSNAT adds or updates the SNAT on each node's GR in L2 networks for each UDN +// Based on the isUDNAdvertised flag, the SNAT matches are slightly different // snat eth.dst == d6:cf:fd:2c:a6:44 169.254.0.12 10.128.0.0/14 // snat eth.dst == d6:cf:fd:2c:a6:44 169.254.0.12 2010:100:200::/64 // these SNATs are required for pod2Egress traffic in LGW mode and pod2SameNode traffic in SGW mode to function properly on UDNs @@ -751,9 +756,12 @@ func (oc *SecondaryLayer2NetworkController) deleteNodeEvent(node *corev1.Node) e // externalIP = "169.254.0.12"; which is the masqueradeIP for this L2 UDN // so all in all we want to condionally SNAT all packets that are coming from pods hosted on this node, // which are leaving via UDN's mpX interface to the UDN's masqueradeIP. -func (oc *SecondaryLayer2NetworkController) addUDNClusterSubnetEgressSNAT(localPodSubnets []*net.IPNet, gwRouterName string) error { +// If isUDNAdvertised is true, then we want to SNAT all packets that are coming from pods on this network +// leaving towards nodeIPs on the cluster to masqueradeIP. If network is advertise then the SNAT looks like this: +// "eth.dst == 0a:58:5d:5d:00:02 && (ip4.dst == $a712973235162149816)" "169.254.0.36" "93.93.0.0/16" +func (oc *SecondaryLayer2NetworkController) addOrUpdateUDNClusterSubnetEgressSNAT(localPodSubnets []*net.IPNet, gwRouterName string, isUDNAdvertised bool) error { outputPort := types.GWRouterToJoinSwitchPrefix + gwRouterName - nats, err := oc.buildUDNEgressSNAT(localPodSubnets, outputPort) + nats, err := oc.buildUDNEgressSNAT(localPodSubnets, outputPort, isUDNAdvertised) if err != nil { return err } @@ -770,25 +778,6 @@ func (oc *SecondaryLayer2NetworkController) addUDNClusterSubnetEgressSNAT(localP return nil } -func (oc *SecondaryLayer2NetworkController) deleteUDNClusterSubnetEgressSNAT(localPodSubnets []*net.IPNet, routerName string) error { - outputPort := types.GWRouterToJoinSwitchPrefix + routerName - nats, err := oc.buildUDNEgressSNAT(localPodSubnets, outputPort) - if err != nil { - return err - } - if len(nats) == 0 { - return nil // nothing to do - } - router := &nbdb.LogicalRouter{ - Name: routerName, - } - if err := libovsdbops.DeleteNATs(oc.nbClient, router, nats...); err != nil { - return fmt.Errorf("failed to delete SNAT for cluster on router: %q for network %q, error: %w", - routerName, oc.GetNetworkName(), err) - } - return nil -} - func (oc *SecondaryLayer2NetworkController) nodeGatewayConfig(node *corev1.Node) (*GatewayConfig, error) { l3GatewayConfig, err := util.ParseNodeL3GatewayAnnotation(node) if err != nil { diff --git a/go-controller/pkg/ovn/secondary_layer3_network_controller.go b/go-controller/pkg/ovn/secondary_layer3_network_controller.go index b2355b9100..e9745fe9b2 100644 --- a/go-controller/pkg/ovn/secondary_layer3_network_controller.go +++ b/go-controller/pkg/ovn/secondary_layer3_network_controller.go @@ -857,7 +857,8 @@ func (oc *SecondaryLayer3NetworkController) addUpdateRemoteNodeEvent(node *corev return err } -// addNodeSubnetEgressSNAT adds the SNAT on each node's ovn-cluster-router in L3 networks +// addOrUpdateUDNNodeSubnetEgressSNAT adds or updates the SNAT on each node's ovn-cluster-router in L3 networks for each UDN +// Based on the isUDNAdvertised flag, the SNAT matches are slightly different // snat eth.dst == d6:cf:fd:2c:a6:44 169.254.0.12 10.128.0.0/24 // snat eth.dst == d6:cf:fd:2c:a6:44 169.254.0.12 2010:100:200::/64 // these SNATs are required for pod2Egress traffic in LGW mode and pod2SameNode traffic in SGW mode to function properly on UDNs @@ -867,9 +868,12 @@ func (oc *SecondaryLayer3NetworkController) addUpdateRemoteNodeEvent(node *corev // externalIP = "169.254.0.12"; which is the masqueradeIP for this L3 UDN // so all in all we want to condionally SNAT all packets that are coming from pods hosted on this node, // which are leaving via UDN's mpX interface to the UDN's masqueradeIP. -func (oc *SecondaryLayer3NetworkController) addUDNNodeSubnetEgressSNAT(localPodSubnets []*net.IPNet, node *corev1.Node) error { +// If isUDNAdvertised is true, then we want to SNAT all packets that are coming from pods on this network +// leaving towards nodeIPs on the cluster to masqueradeIP. If network is advertise then the SNAT looks like this: +// "eth.dst == 0a:58:5d:5d:00:02 && (ip4.dst == $a712973235162149816)" "169.254.0.36" "93.93.0.0/24" +func (oc *SecondaryLayer3NetworkController) addOrUpdateUDNNodeSubnetEgressSNAT(localPodSubnets []*net.IPNet, node *corev1.Node, isUDNAdvertised bool) error { outputPort := types.RouterToSwitchPrefix + oc.GetNetworkScopedName(node.Name) - nats, err := oc.buildUDNEgressSNAT(localPodSubnets, outputPort) + nats, err := oc.buildUDNEgressSNAT(localPodSubnets, outputPort, isUDNAdvertised) if err != nil { return fmt.Errorf("failed to build UDN masquerade SNATs for network %q on node %q, err: %w", oc.GetNetworkName(), node.Name, err) @@ -887,28 +891,6 @@ func (oc *SecondaryLayer3NetworkController) addUDNNodeSubnetEgressSNAT(localPodS return nil } -// deleteUDNNodeSubnetEgressSNAT deletes SNAT rule from network specific -// ovn_cluster_router depending on whether the network is advertised or not -func (oc *SecondaryLayer3NetworkController) deleteUDNNodeSubnetEgressSNAT(localPodSubnets []*net.IPNet, node *corev1.Node) error { - outputPort := types.RouterToSwitchPrefix + oc.GetNetworkScopedName(node.Name) - nats, err := oc.buildUDNEgressSNAT(localPodSubnets, outputPort) - if err != nil { - return fmt.Errorf("failed to build UDN masquerade SNATs for network %q on node %q, err: %w", - oc.GetNetworkName(), node.Name, err) - } - if len(nats) == 0 { - return nil // nothing to do - } - router := &nbdb.LogicalRouter{ - Name: oc.GetNetworkScopedClusterRouterName(), - } - if err := libovsdbops.DeleteNATs(oc.nbClient, router, nats...); err != nil { - return fmt.Errorf("failed to delete SNAT for node subnet on router: %q for network %q, error: %w", - oc.GetNetworkScopedClusterRouterName(), oc.GetNetworkName(), err) - } - return nil -} - func (oc *SecondaryLayer3NetworkController) addNode(node *corev1.Node) ([]*net.IPNet, error) { // Node subnet for the secondary layer3 network is allocated by cluster manager. // Make sure that the node is allocated with the subnet before proceeding @@ -923,19 +905,17 @@ func (oc *SecondaryLayer3NetworkController) addNode(node *corev1.Node) ([]*net.I return nil, err } if util.IsNetworkSegmentationSupportEnabled() && oc.IsPrimaryNetwork() { - if !util.IsPodNetworkAdvertisedAtNode(oc, node.Name) { - if err := oc.addUDNNodeSubnetEgressSNAT(hostSubnets, node); err != nil { - return nil, err - } + isUDNAdvertised := util.IsPodNetworkAdvertisedAtNode(oc, node.Name) + if err := oc.addOrUpdateUDNNodeSubnetEgressSNAT(hostSubnets, node, isUDNAdvertised); err != nil { + return nil, err + } + if !isUDNAdvertised { if util.IsRouteAdvertisementsEnabled() { if err := oc.deleteAdvertisedNetworkIsolation(node.Name); err != nil { return nil, err } } } else { - if err := oc.deleteUDNNodeSubnetEgressSNAT(hostSubnets, node); err != nil { - return nil, err - } if err := oc.addAdvertisedNetworkIsolation(node.Name); err != nil { return nil, err } diff --git a/go-controller/pkg/util/multi_network.go b/go-controller/pkg/util/multi_network.go index fd91edd3be..841ab001b8 100644 --- a/go-controller/pkg/util/multi_network.go +++ b/go-controller/pkg/util/multi_network.go @@ -82,7 +82,6 @@ type NetInfo interface { GetNetworkScopedExtPortName(bridgeID, nodeName string) string GetNetworkScopedLoadBalancerName(lbName string) string GetNetworkScopedLoadBalancerGroupName(lbGroupName string) string - GetNetworkScopedClusterSubnetSNATMatch(nodeName string) string // GetNetInfo is an identity method used to get the specific NetInfo // implementation @@ -543,10 +542,6 @@ func (nInfo *DefaultNetInfo) GetNetworkScopedLoadBalancerGroupName(lbGroupName s return nInfo.GetNetworkScopedName(lbGroupName) } -func (nInfo *DefaultNetInfo) GetNetworkScopedClusterSubnetSNATMatch(_ string) string { - return "" -} - func (nInfo *DefaultNetInfo) canReconcile(netInfo NetInfo) bool { _, ok := netInfo.(*DefaultNetInfo) return ok @@ -738,13 +733,6 @@ func (nInfo *secondaryNetInfo) GetNetworkScopedLoadBalancerGroupName(lbGroupName return nInfo.GetNetworkScopedName(lbGroupName) } -func (nInfo *secondaryNetInfo) GetNetworkScopedClusterSubnetSNATMatch(nodeName string) string { - if nInfo.TopologyType() != types.Layer2Topology { - return "" - } - return fmt.Sprintf("outport == %q", types.GWRouterToExtSwitchPrefix+nInfo.GetNetworkScopedGWRouterName(nodeName)) -} - // getPrefix returns if the logical entities prefix for this network func (nInfo *secondaryNetInfo) getPrefix() string { return GetSecondaryNetworkPrefix(nInfo.netName) From f32731c22d96b250d3d484a713a83441e3fdb401 Mon Sep 17 00:00:00 2001 From: Surya Seetharaman Date: Wed, 2 Jul 2025 10:53:40 +0200 Subject: [PATCH 008/115] BGP,UDN,LGW: Ensure both masqueradeIP and podsubnet ip rules are present Given that some traffic like pod->node and pod->nodeport will be SNATed to nodeIP for UDNs, we will need iprules for both masqueradeIP and nodeIP to be present when networks are advertised. This is nothing complicated as keeping the masqueradeIP dangling around doesn't hurt anything (I hope :)) so for pod->node it follows the normal UDN LGW egress traffic flow: 1) pod->switch->ovn_cluster_router 2) SNAT at the router to masIP 3) ovn_cluster_router->switch->mpX 4) goes out and then reply coming from outside will hit these masqueradeIP rules to come back in since we snated to masqueradeIP on the way out, so we need both podsubnet and masqueradeIP rules for advertised networks for all other traffic no SNATing is done Signed-off-by: Surya Seetharaman --- go-controller/pkg/node/gateway_udn.go | 19 +++++++++++-------- go-controller/pkg/node/gateway_udn_test.go | 13 ++++--------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/go-controller/pkg/node/gateway_udn.go b/go-controller/pkg/node/gateway_udn.go index 026ecd94fc..f7d2e27a01 100644 --- a/go-controller/pkg/node/gateway_udn.go +++ b/go-controller/pkg/node/gateway_udn.go @@ -644,17 +644,20 @@ func (udng *UserDefinedNetworkGateway) getV6MasqueradeIP() (*net.IPNet, error) { // constructUDNVRFIPRules constructs rules that redirect matching packets // into the corresponding UDN VRF routing table. -// If the network is not advertised, an example of the rules we set for a -// network is: -// 2000: from all fwmark 0x1001 lookup 1007 -// 2000: from all to 169.254.0.12 lookup 1007 -// 2000: from all fwmark 0x1002 lookup 1009 -// 2000: from all to 169.254.0.14 lookup 1009 -// If the network is advertised, an example of the rules we set for a network is: +// If the network is not advertised, an example of the rules we set for two +// networks is: +// 2000: from all fwmark 0x1001 lookup 1007 +// 2000: from all to 169.254.0.12 lookup 1007 +// 2000: from all fwmark 0x1002 lookup 1009 +// 2000: from all to 169.254.0.14 lookup 1009 +// If the network is advertised, an example of the rules we set for two +// networks is: // 2000: from all fwmark 0x1001 lookup 1007 // 2000: from all to 10.132.0.0/14 lookup 1007 +// 2000: from all to 169.254.0.12 lookup 1007 // 2000: from all fwmark 0x1001 lookup 1009 // 2000: from all to 10.134.0.0/14 lookup 1009 +// 2000: from all to 169.254.0.14 lookup 1009 func (udng *UserDefinedNetworkGateway) constructUDNVRFIPRules(isNetworkAdvertised bool) ([]netlink.Rule, []netlink.Rule, error) { var addIPRules []netlink.Rule var delIPRules []netlink.Rule @@ -693,7 +696,7 @@ func (udng *UserDefinedNetworkGateway) constructUDNVRFIPRules(isNetworkAdvertise delIPRules = append(delIPRules, subnetIPRules...) default: addIPRules = append(addIPRules, subnetIPRules...) - delIPRules = append(delIPRules, masqIPRules...) + addIPRules = append(addIPRules, masqIPRules...) } return addIPRules, delIPRules, nil } diff --git a/go-controller/pkg/node/gateway_udn_test.go b/go-controller/pkg/node/gateway_udn_test.go index 34848faf7e..0ab0bf573b 100644 --- a/go-controller/pkg/node/gateway_udn_test.go +++ b/go-controller/pkg/node/gateway_udn_test.go @@ -1625,7 +1625,6 @@ func TestConstructUDNVRFIPRules(t *testing.T) { cidr := "" if config.IPv4Mode { cidr = "100.128.0.0/16/24" - } if config.IPv4Mode && config.IPv6Mode { cidr += ",ae70::/60/64" @@ -1711,8 +1710,6 @@ func TestConstructUDNVRFIPRulesPodNetworkAdvertised(t *testing.T) { table: 1007, dst: *ovntest.MustParseIPNet("100.128.0.0/16"), }, - }, - deleteRules: []testRule{ { priority: UDNMasqueradeIPRulePriority, family: netlink.FAMILY_V4, @@ -1738,8 +1735,6 @@ func TestConstructUDNVRFIPRulesPodNetworkAdvertised(t *testing.T) { table: 1009, dst: *ovntest.MustParseIPNet("ae70::/60"), }, - }, - deleteRules: []testRule{ { priority: UDNMasqueradeIPRulePriority, family: netlink.FAMILY_V6, @@ -1777,8 +1772,6 @@ func TestConstructUDNVRFIPRulesPodNetworkAdvertised(t *testing.T) { table: 1010, dst: *ovntest.MustParseIPNet("ae70::/60"), }, - }, - deleteRules: []testRule{ { priority: UDNMasqueradeIPRulePriority, family: netlink.FAMILY_V4, @@ -1813,9 +1806,9 @@ func TestConstructUDNVRFIPRulesPodNetworkAdvertised(t *testing.T) { cidr = "100.128.0.0/16/24" } if config.IPv4Mode && config.IPv6Mode { - cidr += ",ae70::/60" + cidr += ",ae70::/60/64" } else if config.IPv6Mode { - cidr = "ae70::/60" + cidr = "ae70::/60/64" } nad := ovntest.GenerateNAD("bluenet", "rednad", "greenamespace", types.Layer3Topology, cidr, types.NetworkRolePrimary) @@ -1844,6 +1837,8 @@ func TestConstructUDNVRFIPRulesPodNetworkAdvertised(t *testing.T) { udnGateway.vrfTableId = test.vrftableID rules, delRules, err := udnGateway.constructUDNVRFIPRules(true) g.Expect(err).ToNot(HaveOccurred()) + g.Expect(rules).To(HaveLen(len(test.expectedRules))) + g.Expect(delRules).To(HaveLen(len(test.deleteRules))) for i, rule := range rules { g.Expect(rule.Priority).To(Equal(test.expectedRules[i].priority)) g.Expect(rule.Table).To(Equal(test.expectedRules[i].table)) From 501bcbff9f08ce32b7b3251f16b389b8a3ccdecc Mon Sep 17 00:00:00 2001 From: Surya Seetharaman Date: Wed, 9 Jul 2025 11:10:16 +0200 Subject: [PATCH 009/115] Convert LGW postrouting rules to NFT This commit is a prep-commit that converts the LGW POSTROUTING chain rules from IPT to NFT. Why do we need to do this now? It's because for BGP we want to use the PMTUD remote nodeIP NFT sets to also do conditional masquerading in Local Gateway mode for BGP when traffic leaves UDNs towards other nodes in the cluster or other nodeports. Given PMTUD rules are in NFT but the lgw and udn masquerade rules are in IPT - we'd need to pick one to express all - since we want to move to NFT, its better to go that route. Below is how the rules look like. chain ovn-kube-local-gw-masq { comment "OVN local gateway masquerade" type nat hook postrouting priority srcnat; policy accept; ip saddr 169.254.0.1 masquerade ip6 saddr fd69::1 masquerade jump ovn-kube-pod-subnet-masq jump ovn-kube-udn-masq } chain ovn-kube-pod-subnet-masq { ip saddr 10.244.2.0/24 masquerade ip6 saddr fd00:10:244:1::/64 masquerade } chain ovn-kube-udn-masq { comment "OVN UDN masquerade" ip saddr != 169.254.0.0/29 ip daddr != 10.96.0.0/16 ip saddr 169.254.0.0/17 masquerade ip6 saddr != fd69::/125 ip daddr != fd00:10:96::/112 ip6 saddr fd69::/112 masquerade } This commit was AI-Cursor-gemini/claude assissted under my supervision/prompting/reviewing/back-forth iterations Signed-off-by: Surya Seetharaman --- go-controller/pkg/node/gateway.go | 4 +- .../pkg/node/gateway_init_linux_test.go | 31 +- go-controller/pkg/node/gateway_iptables.go | 167 +--------- go-controller/pkg/node/gateway_localnet.go | 24 +- go-controller/pkg/node/gateway_nftables.go | 299 ++++++++++++++++++ 5 files changed, 342 insertions(+), 183 deletions(-) diff --git a/go-controller/pkg/node/gateway.go b/go-controller/pkg/node/gateway.go index 9b43fc95a5..7f11a0b813 100644 --- a/go-controller/pkg/node/gateway.go +++ b/go-controller/pkg/node/gateway.go @@ -522,8 +522,8 @@ func (g *gateway) updateSNATRules() error { subnets := util.IPsToNetworkIPs(g.nodeIPManager.mgmtPort.GetAddresses()...) if g.GetDefaultPodNetworkAdvertised() || config.Gateway.Mode != config.GatewayModeLocal { - return delLocalGatewayPodSubnetNATRules(subnets...) + return delLocalGatewayPodSubnetNFTRules() } - return addLocalGatewayPodSubnetNATRules(subnets...) + return addLocalGatewayPodSubnetNFTRules(subnets...) } diff --git a/go-controller/pkg/node/gateway_init_linux_test.go b/go-controller/pkg/node/gateway_init_linux_test.go index 6e8aadc0f5..9bc0cc5401 100644 --- a/go-controller/pkg/node/gateway_init_linux_test.go +++ b/go-controller/pkg/node/gateway_init_linux_test.go @@ -80,6 +80,17 @@ add chain inet ovn-kubernetes udn-service-prerouting { type filter hook prerouti add rule inet ovn-kubernetes udn-service-prerouting iifname != %s jump udn-service-mark add chain inet ovn-kubernetes udn-service-output { type filter hook output priority -150 ; comment "UDN services packet mark - Output" ; } add rule inet ovn-kubernetes udn-service-output jump udn-service-mark +add chain inet ovn-kubernetes ovn-kube-udn-masq { comment "OVN UDN masquerade" ; } +add rule inet ovn-kubernetes ovn-kube-udn-masq ip saddr != 169.254.169.0/29 ip daddr != 172.16.1.0/24 ip saddr 169.254.169.0/24 masquerade +add rule inet ovn-kubernetes ovn-kube-local-gw-masq jump ovn-kube-udn-masq +` + +const baseLGWNFTablesRules = ` +add rule inet ovn-kubernetes ovn-kube-local-gw-masq ip saddr 169.254.169.1 masquerade +add chain inet ovn-kubernetes ovn-kube-local-gw-masq { type nat hook postrouting priority 100 ; comment "OVN local gateway masquerade" ; } +add rule inet ovn-kubernetes ovn-kube-local-gw-masq jump ovn-kube-pod-subnet-masq +add rule inet ovn-kubernetes ovn-kube-pod-subnet-masq ip saddr 10.1.1.0/24 masquerade +add chain inet ovn-kubernetes ovn-kube-pod-subnet-masq ` func getBaseNFTRules(mgmtPort string) string { @@ -90,6 +101,10 @@ func getBaseNFTRules(mgmtPort string) string { return ret } +func getBaseLGWNFTablesRules(mgmtPort string) string { + return getBaseNFTRules(mgmtPort) + baseLGWNFTablesRules +} + func shareGatewayInterfaceTest(app *cli.App, testNS ns.NetNS, eth0Name, eth0MAC, eth0GWIP, eth0CIDR string, gatewayVLANID uint, l netlink.Link, hwOffload, setNodeIP bool) { const mtu string = "1234" @@ -1350,10 +1365,6 @@ OFPT_GET_CONFIG_REPLY (xid=0x4): frags=normal miss_send_len=0` "OVN-KUBE-EXTERNALIP": []string{ fmt.Sprintf("-p %s -d %s --dport %v -j DNAT --to-destination %s:%v", service.Spec.Ports[0].Protocol, externalIP, service.Spec.Ports[0].Port, service.Spec.ClusterIP, service.Spec.Ports[0].Port), }, - "POSTROUTING": []string{ - "-s 169.254.169.1 -j MASQUERADE", - "-s 10.1.1.0/24 -j MASQUERADE", - }, "OVN-KUBE-ETP": []string{}, "OVN-KUBE-ITP": []string{}, }, @@ -1379,16 +1390,6 @@ OFPT_GET_CONFIG_REPLY (xid=0x4): frags=normal miss_send_len=0` "OVN-KUBE-ITP": []string{}, }, } - if util.IsNetworkSegmentationSupportEnabled() { - expectedTables["nat"]["POSTROUTING"] = append(expectedTables["nat"]["POSTROUTING"], - "-j OVN-KUBE-UDN-MASQUERADE", - ) - expectedTables["nat"]["OVN-KUBE-UDN-MASQUERADE"] = append(expectedTables["nat"]["OVN-KUBE-UDN-MASQUERADE"], - "-s 169.254.169.0/29 -j RETURN", // this guarantees we don't SNAT default network masqueradeIPs - "-d 172.16.1.0/24 -j RETURN", // this guarantees we don't SNAT service traffic - "-s 169.254.169.0/24 -j MASQUERADE", // this guarantees we SNAT all UDN MasqueradeIPs traffic leaving the node - ) - } f4 := iptV4.(*util.FakeIPTables) err = f4.MatchState(expectedTables, map[util.FakePolicyKey]string{{ Table: "filter", @@ -1405,7 +1406,7 @@ OFPT_GET_CONFIG_REPLY (xid=0x4): frags=normal miss_send_len=0` err = f6.MatchState(expectedTables, nil) Expect(err).NotTo(HaveOccurred()) - expectedNFT := getBaseNFTRules(types.K8sMgmtIntfName) + expectedNFT := getBaseLGWNFTablesRules(types.K8sMgmtIntfName) err = nodenft.MatchNFTRules(expectedNFT, nft.Dump()) Expect(err).NotTo(HaveOccurred()) diff --git a/go-controller/pkg/node/gateway_iptables.go b/go-controller/pkg/node/gateway_iptables.go index e9b6b12387..90bffbe91f 100644 --- a/go-controller/pkg/node/gateway_iptables.go +++ b/go-controller/pkg/node/gateway_iptables.go @@ -21,11 +21,10 @@ import ( ) const ( - iptableNodePortChain = "OVN-KUBE-NODEPORT" // called from nat-PREROUTING and nat-OUTPUT - iptableExternalIPChain = "OVN-KUBE-EXTERNALIP" // called from nat-PREROUTING and nat-OUTPUT - iptableETPChain = "OVN-KUBE-ETP" // called from nat-PREROUTING only - iptableITPChain = "OVN-KUBE-ITP" // called from mangle-OUTPUT and nat-OUTPUT - iptableUDNMasqueradeChain = "OVN-KUBE-UDN-MASQUERADE" // called from nat-POSTROUTING + iptableNodePortChain = "OVN-KUBE-NODEPORT" // called from nat-PREROUTING and nat-OUTPUT + iptableExternalIPChain = "OVN-KUBE-EXTERNALIP" // called from nat-PREROUTING and nat-OUTPUT + iptableETPChain = "OVN-KUBE-ETP" // called from nat-PREROUTING only + iptableITPChain = "OVN-KUBE-ITP" // called from mangle-OUTPUT and nat-OUTPUT ) func clusterIPTablesProtocols() []iptables.Protocol { @@ -69,29 +68,11 @@ func restoreIptRulesFiltered(rules []nodeipt.Rule, filter map[string]map[string] return nodeipt.RestoreRulesFiltered(rules, filter) } -// appendIptRules adds the provided rules in an append fashion -// i.e each rule gets added at the last position in the chain -func appendIptRules(rules []nodeipt.Rule) error { - return nodeipt.AddRules(rules, true) -} - // deleteIptRules removes provided rules from the chain func deleteIptRules(rules []nodeipt.Rule) error { return nodeipt.DelRules(rules) } -// ensureChain ensures that a chain exists within a table -func ensureChain(table, chain string) error { - for _, proto := range clusterIPTablesProtocols() { - ipt, err := util.GetIPTablesHelper(proto) - if err != nil { - return fmt.Errorf("failed to get IPTables helper to add UDN chain: %v", err) - } - addChaintoTable(ipt, table, chain) - } - return nil -} - func getGatewayInitRules(chain string, proto iptables.Protocol) []nodeipt.Rule { iptRules := []nodeipt.Rule{} if chain == iptableITPChain { @@ -403,123 +384,8 @@ func getLocalGatewayFilterRules(ifname string, cidr *net.IPNet) []nodeipt.Rule { } } -func getLocalGatewayPodSubnetNATRules(cidr *net.IPNet) []nodeipt.Rule { - protocol := getIPTablesProtocol(cidr.IP.String()) - return []nodeipt.Rule{ - { - Table: "nat", - Chain: "POSTROUTING", - Args: []string{ - "-s", cidr.String(), - "-j", "MASQUERADE", - }, - Protocol: protocol, - }, - } -} - -// getUDNMasqueradeRules is only called for local-gateway-mode -func getUDNMasqueradeRules(protocol iptables.Protocol) []nodeipt.Rule { - // the following rules are actively used only for the UDN Feature: - // -A POSTROUTING -j OVN-KUBE-UDN-MASQUERADE - // -A OVN-KUBE-UDN-MASQUERADE -s 169.254.0.0/29 -j RETURN - // -A OVN-KUBE-UDN-MASQUERADE -d 10.96.0.0/16 -j RETURN - // -A OVN-KUBE-UDN-MASQUERADE -s 169.254.0.0/17 -j MASQUERADE - // NOTE: Ordering is important here, the RETURN must come before - // the MASQUERADE rule. Please don't change the ordering. - srcUDNMasqueradePrefix := config.Gateway.V4MasqueradeSubnet - ipFamily := utilnet.IPv4 - if protocol == iptables.ProtocolIPv6 { - srcUDNMasqueradePrefix = config.Gateway.V6MasqueradeSubnet - ipFamily = utilnet.IPv6 - } - // defaultNetworkReservedMasqueradePrefix contains the first 6 IPs in the - // masquerade range that shouldn't be masqueraded. Hence it's always 3 bits (8 - // IPs) wide, regardless of IP family. - _, ipnet, _ := net.ParseCIDR(srcUDNMasqueradePrefix) - _, len := ipnet.Mask.Size() - defaultNetworkReservedMasqueradePrefix := fmt.Sprintf("%s/%d", ipnet.IP.String(), len-3) - - rules := []nodeipt.Rule{ - { - Table: "nat", - Chain: "POSTROUTING", - Args: []string{"-j", iptableUDNMasqueradeChain}, // NOTE: AddRules will take care of creating the chain - Protocol: protocol, - }, - { - Table: "nat", - Chain: iptableUDNMasqueradeChain, - Args: []string{ - "-s", defaultNetworkReservedMasqueradePrefix, - "-j", "RETURN", - }, - Protocol: protocol, - }, - } - for _, svcCIDR := range config.Kubernetes.ServiceCIDRs { - if utilnet.IPFamilyOfCIDR(svcCIDR) != ipFamily { - continue - } - rules = append(rules, - nodeipt.Rule{ - Table: "nat", - Chain: iptableUDNMasqueradeChain, - Args: []string{ - "-d", svcCIDR.String(), - "-j", "RETURN", - }, - Protocol: protocol, - }, - ) - } - rules = append(rules, - nodeipt.Rule{ - Table: "nat", - Chain: iptableUDNMasqueradeChain, - Args: []string{ - "-s", srcUDNMasqueradePrefix, - "-j", "MASQUERADE", - }, - Protocol: protocol, - }, - ) - return rules -} - -func getLocalGatewayNATRules(cidr *net.IPNet) []nodeipt.Rule { - // Allow packets to/from the gateway interface in case defaults deny - protocol := getIPTablesProtocol(cidr.IP.String()) - masqueradeIP := config.Gateway.MasqueradeIPs.V4OVNMasqueradeIP - if protocol == iptables.ProtocolIPv6 { - masqueradeIP = config.Gateway.MasqueradeIPs.V6OVNMasqueradeIP - } - rules := append( - []nodeipt.Rule{ - { - Table: "nat", - Chain: "POSTROUTING", - Args: []string{ - "-s", masqueradeIP.String(), - "-j", "MASQUERADE", - }, - Protocol: protocol, - }, - }, - getLocalGatewayPodSubnetNATRules(cidr)..., - ) - - // FIXME(tssurya): If the feature is disabled we should be removing - // these rules - if util.IsNetworkSegmentationSupportEnabled() { - rules = append(rules, getUDNMasqueradeRules(protocol)...) - } - - return rules -} - -// initLocalGatewayNATRules sets up iptables rules for interfaces -func initLocalGatewayNATRules(ifname string, cidr *net.IPNet) error { +// initLocalGatewayIPTFilterRules sets up iptables rules for interfaces +func initLocalGatewayIPTFilterRules(ifname string, cidr *net.IPNet) error { // Insert the filter table rules because they need to be evaluated BEFORE the DROP rules // we have for forwarding. DO NOT change the ordering; specially important // during SGW->LGW rollouts and restarts. @@ -527,25 +393,8 @@ func initLocalGatewayNATRules(ifname string, cidr *net.IPNet) error { if err != nil { return fmt.Errorf("unable to insert forwarding rules %v", err) } - // append the masquerade rules in POSTROUTING table since that needs to be - // evaluated last. - return appendIptRules(getLocalGatewayNATRules(cidr)) -} - -func addLocalGatewayPodSubnetNATRules(cidrs ...*net.IPNet) error { - var rules []nodeipt.Rule - for _, cidr := range cidrs { - rules = append(rules, getLocalGatewayPodSubnetNATRules(cidr)...) - } - return appendIptRules(rules) -} - -func delLocalGatewayPodSubnetNATRules(cidrs ...*net.IPNet) error { - var rules []nodeipt.Rule - for _, cidr := range cidrs { - rules = append(rules, getLocalGatewayPodSubnetNATRules(cidr)...) - } - return deleteIptRules(rules) + // NOTE: nftables masquerade rules are now handled separately in initLocalGatewayNFTNATRules + return nil } func addChaintoTable(ipt util.IPTablesHelper, tableName, chain string) { diff --git a/go-controller/pkg/node/gateway_localnet.go b/go-controller/pkg/node/gateway_localnet.go index e0cc822844..6b8ed9aa0b 100644 --- a/go-controller/pkg/node/gateway_localnet.go +++ b/go-controller/pkg/node/gateway_localnet.go @@ -17,11 +17,11 @@ import ( func initLocalGateway(hostSubnets []*net.IPNet, mgmtPort managementport.Interface) error { klog.Info("Adding iptables masquerading rules for new local gateway") - if util.IsNetworkSegmentationSupportEnabled() { - if err := ensureChain("nat", iptableUDNMasqueradeChain); err != nil { - return fmt.Errorf("failed to ensure chain %s in NAT table: %w", iptableUDNMasqueradeChain, err) - } - } + + var allCIDRs []*net.IPNet + ifName := mgmtPort.GetInterfaceName() + + // First pass: collect all CIDRs and setup iptables filter rules per interface for _, hostSubnet := range hostSubnets { // local gateway mode uses mp0 as default path for all ingress traffic into OVN nextHop, err := util.MatchFirstIPNetFamily(utilnet.IsIPv6CIDR(hostSubnet), mgmtPort.GetAddresses()) @@ -32,11 +32,21 @@ func initLocalGateway(hostSubnets []*net.IPNet, mgmtPort managementport.Interfac // add iptables masquerading for mp0 to exit the host for egress cidr := nextHop.IP.Mask(nextHop.Mask) cidrNet := &net.IPNet{IP: cidr, Mask: nextHop.Mask} - ifName := mgmtPort.GetInterfaceName() - if err := initLocalGatewayNATRules(ifName, cidrNet); err != nil { + allCIDRs = append(allCIDRs, cidrNet) + + // Setup iptables filter rules for this interface/CIDR + if err := initLocalGatewayIPTFilterRules(ifName, cidrNet); err != nil { return fmt.Errorf("failed to add local NAT rules for: %s, err: %v", ifName, err) } } + + // setup nftables masquerade rules for all CIDRs (v4, v6 or dualstack) + if len(allCIDRs) > 0 { + if err := initLocalGatewayNFTNATRules(allCIDRs...); err != nil { + return fmt.Errorf("failed to setup nftables masquerade rules: %w", err) + } + } + return nil } diff --git a/go-controller/pkg/node/gateway_nftables.go b/go-controller/pkg/node/gateway_nftables.go index 842bb417d1..c2de7aa5e7 100644 --- a/go-controller/pkg/node/gateway_nftables.go +++ b/go-controller/pkg/node/gateway_nftables.go @@ -6,12 +6,14 @@ package node import ( "context" "fmt" + "net" "strings" corev1 "k8s.io/api/core/v1" utilnet "k8s.io/utils/net" "sigs.k8s.io/knftables" + "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/config" "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/node/bridgeconfig" nodenft "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/node/nftables" "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/types" @@ -27,6 +29,13 @@ import ( // use an "accept" rule to override a later "drop" rule), then those rules will need to // either both be iptables or both be nftables. +// nftables chain names +const ( + nftablesLocalGatewayMasqChain = "ovn-kube-local-gw-masq" + nftablesPodSubnetMasqChain = "ovn-kube-pod-subnet-masq" + nftablesUDNMasqChain = "ovn-kube-udn-masq" +) + // getNoSNATNodePortRules returns elements to add to the "mgmtport-no-snat-nodeports" // set to prevent SNAT of sourceIP when passing through the management port, for an // `externalTrafficPolicy: Local` service with NodePorts. @@ -186,3 +195,293 @@ func getUDNNFTRules(service *corev1.Service, netConfig *bridgeconfig.BridgeUDNCo } return rules } + +// getLocalGatewayPodSubnetMasqueradeNFTRule creates a rule for masquerading traffic from the pod subnet CIDR +// in local gateway node in a seperate chain which is then called from local gateway masquerade chain. +// +// chain ovn-kube-pod-subnet-masq { +// ip saddr 10.244.0.0/24 masquerade +// ip6 saddr fd00:10:244:1::/64 masquerade +// } +func getLocalGatewayPodSubnetMasqueradeNFTRule(cidr *net.IPNet) (*knftables.Rule, error) { + // Create the rule for masquerading traffic from the CIDR + ipPrefix := "ip" + if utilnet.IsIPv6CIDR(cidr) { + ipPrefix = "ip6" + } + + rule := &knftables.Rule{ + Rule: knftables.Concat( + ipPrefix, "saddr", cidr, + "masquerade", + ), + Chain: nftablesPodSubnetMasqChain, + } + + return rule, nil +} + +// getLocalGatewayNATNFTRules returns the nftables rules for local gateway NAT including masquerade IP rule, +// pod subnet rules, and UDN masquerade rules (if network segmentation is enabled). +// This function supports dual-stack by accepting multiple CIDRs and generating rules for all IP families. +// +// chain ovn-kube-local-gw-masq { +// comment "OVN local gateway masquerade" +// type nat hook postrouting priority srcnat; policy accept; +// ip saddr 169.254.0.1 masquerade +// ip6 saddr fd69::1 masquerade +// jump ovn-kube-pod-subnet-masq +// jump ovn-kube-udn-masq +// } +func getLocalGatewayNATNFTRules(cidrs ...*net.IPNet) ([]*knftables.Rule, error) { + var rules []*knftables.Rule + + // Process each CIDR to support dual-stack + for _, cidr := range cidrs { + // Determine IP version and masquerade IP + isIPv6 := utilnet.IsIPv6CIDR(cidr) + var masqueradeIP net.IP + var ipPrefix string + if isIPv6 { + masqueradeIP = config.Gateway.MasqueradeIPs.V6OVNMasqueradeIP + ipPrefix = "ip6" + } else { + masqueradeIP = config.Gateway.MasqueradeIPs.V4OVNMasqueradeIP + ipPrefix = "ip" + } + + // Rule1: Masquerade IP rule for the main chain + masqRule := &knftables.Rule{ + Chain: nftablesLocalGatewayMasqChain, + Rule: knftables.Concat( + ipPrefix, "saddr", masqueradeIP, + "masquerade", + ), + } + rules = append(rules, masqRule) + + // Rule2: Pod subnet NAT rule for the pod subnet chain + podSubnetRule, err := getLocalGatewayPodSubnetMasqueradeNFTRule(cidr) + if err != nil { + return nil, fmt.Errorf("failed to create pod subnet masquerade rule: %w", err) + } + rules = append(rules, podSubnetRule) + } + + // Rule 3: UDN masquerade rules (if network segmentation is enabled) + if util.IsNetworkSegmentationSupportEnabled() { + if config.IPv4Mode { + udnRules, err := getUDNMasqueradeNFTRules(utilnet.IPv4) + if err != nil { + return nil, fmt.Errorf("failed to create IPv4 UDN masquerade rules: %w", err) + } + rules = append(rules, udnRules...) + } + if config.IPv6Mode { + udnRules, err := getUDNMasqueradeNFTRules(utilnet.IPv6) + if err != nil { + return nil, fmt.Errorf("failed to create IPv6 UDN masquerade rules: %w", err) + } + rules = append(rules, udnRules...) + } + } + + return rules, nil +} + +// getUDNMasqueradeNFTRules returns the nftables rules for UDN masquerade. +// Chain creation is handled separately by setupLocalGatewayNATNFTRules. +// +// chain ovn-kube-udn-masq { +// comment "OVN UDN masquerade" +// ip saddr != 169.254.0.0/29 ip daddr != 10.96.0.0/16 ip saddr 169.254.0.0/17 masquerade +// ip6 saddr != fd69::/125 ip daddr != fd00:10:96::/112 ip6 saddr fd69::/112 masquerade +// } +func getUDNMasqueradeNFTRules(ipFamily utilnet.IPFamily) ([]*knftables.Rule, error) { + var rules []*knftables.Rule + + // Determine subnet and IP family + srcUDNMasqueradePrefix := config.Gateway.V4MasqueradeSubnet + ipPrefix := "ip" + if ipFamily == utilnet.IPv6 { + srcUDNMasqueradePrefix = config.Gateway.V6MasqueradeSubnet + ipPrefix = "ip6" + } + + // Calculate reserved masquerade prefix (first 8 IPs) + _, ipnet, err := net.ParseCIDR(srcUDNMasqueradePrefix) + if err != nil { + return nil, fmt.Errorf("failed to parse UDN masquerade subnet: %w", err) + } + _, prefixLen := ipnet.Mask.Size() + defaultNetworkReservedMasqueradePrefix := fmt.Sprintf("%s/%d", ipnet.IP.String(), prefixLen-3) + + // Rule: RETURN for reserved masquerade prefix and service CIDRs + // rest of the traffic is masqueraded + + for _, svcCIDR := range config.Kubernetes.ServiceCIDRs { + if utilnet.IPFamilyOfCIDR(svcCIDR) != ipFamily { + continue + } + masqueradeRule := &knftables.Rule{ + Chain: nftablesUDNMasqChain, + Rule: knftables.Concat( + ipPrefix, "saddr", "!=", defaultNetworkReservedMasqueradePrefix, // this guarantees we don't SNAT default network masqueradeIPs + ipPrefix, "daddr", "!=", svcCIDR, // this guarantees we don't SNAT service traffic + ipPrefix, "saddr", srcUDNMasqueradePrefix, // this guarantees we SNAT all UDN MasqueradeIPs traffic leaving the node + "masquerade", + ), + } + rules = append(rules, masqueradeRule) + } + + return rules, nil +} + +// initLocalGatewayNFTNATRules sets up nftables rules for local gateway NAT functionality +// This function supports dual-stack by accepting multiple CIDRs and generating rules for all IP families +func initLocalGatewayNFTNATRules(cidrs ...*net.IPNet) error { + nft, err := nodenft.GetNFTablesHelper() + if err != nil { + return fmt.Errorf("failed to get nftables helper: %w", err) + } + + // Create transaction and apply all chains and rules + tx := nft.NewTransaction() + + // Create main local gateway masquerade chain + localGwMasqChain := &knftables.Chain{ + Name: nftablesLocalGatewayMasqChain, + Comment: knftables.PtrTo("OVN local gateway masquerade"), + Type: knftables.PtrTo(knftables.NATType), + Hook: knftables.PtrTo(knftables.PostroutingHook), + Priority: knftables.PtrTo(knftables.SNATPriority), + } + tx.Add(localGwMasqChain) + + // Create dedicated pod subnet masquerade chain + podSubnetMasqChain := &knftables.Chain{ + Name: nftablesPodSubnetMasqChain, + } + tx.Add(podSubnetMasqChain) + + // Create UDN masquerade chain only if network segmentation is enabled + var udnMasqChain *knftables.Chain + if util.IsNetworkSegmentationSupportEnabled() { + udnMasqChain = &knftables.Chain{ + Name: nftablesUDNMasqChain, + Comment: knftables.PtrTo("OVN UDN masquerade"), + } + tx.Add(udnMasqChain) + } + + // Flush existing chains to ensure clean state + tx.Flush(localGwMasqChain) + tx.Flush(podSubnetMasqChain) + if util.IsNetworkSegmentationSupportEnabled() { + tx.Flush(udnMasqChain) + } + + // Get the existing local gateway NAT rules + localGwRules, err := getLocalGatewayNATNFTRules(cidrs...) + if err != nil { + return fmt.Errorf("failed to get local gateway NAT rules: %w", err) + } + + // Add the main local gateway NAT rules + for _, rule := range localGwRules { + tx.Add(rule) + } + + // Add jump rule from main chain to pod subnet chain + jumpToPodSubnetRule := &knftables.Rule{ + Chain: nftablesLocalGatewayMasqChain, + Rule: knftables.Concat( + "jump", nftablesPodSubnetMasqChain, + ), + } + tx.Add(jumpToPodSubnetRule) + + // Add jump rule to UDN chain only if network segmentation is enabled + if util.IsNetworkSegmentationSupportEnabled() { + jumpToUDNRule := &knftables.Rule{ + Chain: nftablesLocalGatewayMasqChain, + Rule: knftables.Concat( + "jump", nftablesUDNMasqChain, + ), + } + tx.Add(jumpToUDNRule) + } + + err = nft.Run(context.TODO(), tx) + if err != nil { + return fmt.Errorf("failed to setup local gateway NAT nftables rules: %w", err) + } + + return nil +} + +// addLocalGatewayPodSubnetNFTRules adds nftables rules for pod subnet masquerading for multiple CIDRs +// These rules are added to the dedicated pod subnet masquerade chain. +func addLocalGatewayPodSubnetNFTRules(cidrs ...*net.IPNet) error { + nft, err := nodenft.GetNFTablesHelper() + if err != nil { + return fmt.Errorf("failed to get nftables helper: %w", err) + } + + tx := nft.NewTransaction() + + // Ensure the pod subnet chain exists + podSubnetChain := &knftables.Chain{ + Name: nftablesPodSubnetMasqChain, + } + tx.Add(podSubnetChain) + + // Flush the chain to remove all existing rules + tx.Flush(podSubnetChain) + + for _, cidr := range cidrs { + rule, err := getLocalGatewayPodSubnetMasqueradeNFTRule(cidr) + if err != nil { + return fmt.Errorf("failed to create nftables rules for CIDR %s: %w", cidr.String(), err) + } + + // Add the rule + tx.Add(rule) + } + + if err := nft.Run(context.TODO(), tx); err != nil { + return fmt.Errorf("failed to add pod subnet NAT rules: %w", err) + } + + return nil +} + +// delLocalGatewayPodSubnetNFTRules removes nftables rules for pod subnet masquerading for multiple CIDRs +// Since we use a separate chain, we can simply flush it to remove all pod subnet rules. +func delLocalGatewayPodSubnetNFTRules() error { + nft, err := nodenft.GetNFTablesHelper() + if err != nil { + return fmt.Errorf("failed to get nftables helper: %w", err) + } + + tx := nft.NewTransaction() + + // In shared gateway mode, this chain might not exist if its + // not migration from local gateway mode. In that case, let's + // use the idiomatic way of adding the chain before trying to flush it. + // I anyways also have the knftables.IsNotFound() check in the caller later. + tx.Add(&knftables.Chain{ + Name: nftablesPodSubnetMasqChain, + }) + + // Simply flush the dedicated pod subnet masquerade chain + // This removes all pod subnet masquerade rules at once + tx.Flush(&knftables.Chain{Name: nftablesPodSubnetMasqChain}) + + if err := nft.Run(context.TODO(), tx); err != nil && !knftables.IsNotFound(err) { + return fmt.Errorf("failed to delete pod subnet NAT rules: %w", err) + } + + return nil +} From a67872dc389b80d65029c8a01c56299ed39240b6 Mon Sep 17 00:00:00 2001 From: Surya Seetharaman Date: Wed, 9 Jul 2025 11:11:50 +0200 Subject: [PATCH 010/115] rename/reuse pmtud nft sets to remote-node-ips let's reuse the pmtud address-set ips of the remote nodes ips also for bgp advertised networks cSNAT Signed-off-by: Surya Seetharaman --- .../node/default_node_network_controller.go | 18 +++++------ .../default_node_network_controller_test.go | 32 +++++++++---------- go-controller/pkg/node/node_nftables.go | 12 +++---- go-controller/pkg/types/const.go | 8 ++--- 4 files changed, 35 insertions(+), 35 deletions(-) diff --git a/go-controller/pkg/node/default_node_network_controller.go b/go-controller/pkg/node/default_node_network_controller.go index f1281980a8..db7d26802d 100644 --- a/go-controller/pkg/node/default_node_network_controller.go +++ b/go-controller/pkg/node/default_node_network_controller.go @@ -188,7 +188,7 @@ func NewDefaultNodeNetworkController(cnnci *CommonNodeNetworkControllerInfo, net nc.initRetryFrameworkForNode() - err = setupPMTUDNFTSets() + err = setupRemoteNodeNFTSets() if err != nil { return nil, fmt.Errorf("failed to setup PMTUD nftables sets: %w", err) } @@ -1528,12 +1528,12 @@ func (nc *DefaultNodeNetworkController) addOrUpdateNode(node *corev1.Node) error klog.Infof("Adding remote node %q, IP: %s to PMTUD blocking rules", node.Name, nodeIP) if utilnet.IsIPv4(nodeIP) { nftElems = append(nftElems, &knftables.Element{ - Set: types.NFTNoPMTUDRemoteNodeIPsv4, + Set: types.NFTRemoteNodeIPsv4, Key: []string{nodeIP.String()}, }) } else { nftElems = append(nftElems, &knftables.Element{ - Set: types.NFTNoPMTUDRemoteNodeIPsv6, + Set: types.NFTRemoteNodeIPsv6, Key: []string{nodeIP.String()}, }) } @@ -1557,12 +1557,12 @@ func removePMTUDNodeNFTRules(nodeIPs []net.IP) error { // Remove IPs from NFT sets if utilnet.IsIPv4(nodeIP) { nftElems = append(nftElems, &knftables.Element{ - Set: types.NFTNoPMTUDRemoteNodeIPsv4, + Set: types.NFTRemoteNodeIPsv4, Key: []string{nodeIP.String()}, }) } else { nftElems = append(nftElems, &knftables.Element{ - Set: types.NFTNoPMTUDRemoteNodeIPsv6, + Set: types.NFTRemoteNodeIPsv6, Key: []string{nodeIP.String()}, }) } @@ -1622,21 +1622,21 @@ func (nc *DefaultNodeNetworkController) syncNodes(objs []interface{}) error { // Remove IPs from NFT sets if utilnet.IsIPv4(nodeIP) { keepNFTSetElemsV4 = append(keepNFTSetElemsV4, &knftables.Element{ - Set: types.NFTNoPMTUDRemoteNodeIPsv4, + Set: types.NFTRemoteNodeIPsv4, Key: []string{nodeIP.String()}, }) } else { keepNFTSetElemsV6 = append(keepNFTSetElemsV6, &knftables.Element{ - Set: types.NFTNoPMTUDRemoteNodeIPsv6, + Set: types.NFTRemoteNodeIPsv6, Key: []string{nodeIP.String()}, }) } } } - if err := recreateNFTSet(types.NFTNoPMTUDRemoteNodeIPsv4, keepNFTSetElemsV4); err != nil { + if err := recreateNFTSet(types.NFTRemoteNodeIPsv4, keepNFTSetElemsV4); err != nil { errors = append(errors, err) } - if err := recreateNFTSet(types.NFTNoPMTUDRemoteNodeIPsv6, keepNFTSetElemsV6); err != nil { + if err := recreateNFTSet(types.NFTRemoteNodeIPsv6, keepNFTSetElemsV6); err != nil { errors = append(errors, err) } diff --git a/go-controller/pkg/node/default_node_network_controller_test.go b/go-controller/pkg/node/default_node_network_controller_test.go index a1413a7dd1..24c3141357 100644 --- a/go-controller/pkg/node/default_node_network_controller_test.go +++ b/go-controller/pkg/node/default_node_network_controller_test.go @@ -38,18 +38,18 @@ import ( const v4PMTUDNFTRules = ` add table inet ovn-kubernetes -add rule inet ovn-kubernetes no-pmtud ip daddr @no-pmtud-remote-node-ips-v4 meta l4proto icmp icmp type 3 icmp code 4 counter drop +add rule inet ovn-kubernetes no-pmtud ip daddr @remote-node-ips-v4 meta l4proto icmp icmp type 3 icmp code 4 counter drop add chain inet ovn-kubernetes no-pmtud { type filter hook output priority 0 ; comment "Block egress needs frag/packet too big to remote k8s nodes" ; } -add set inet ovn-kubernetes no-pmtud-remote-node-ips-v4 { type ipv4_addr ; comment "Block egress ICMP needs frag to remote Kubernetes nodes" ; } -add set inet ovn-kubernetes no-pmtud-remote-node-ips-v6 { type ipv6_addr ; comment "Block egress ICMPv6 packet too big to remote Kubernetes nodes" ; } +add set inet ovn-kubernetes remote-node-ips-v4 { type ipv4_addr ; comment "Block egress ICMP needs frag to remote Kubernetes nodes" ; } +add set inet ovn-kubernetes remote-node-ips-v6 { type ipv6_addr ; comment "Block egress ICMPv6 packet too big to remote Kubernetes nodes" ; } ` const v6PMTUDNFTRules = ` add table inet ovn-kubernetes -add rule inet ovn-kubernetes no-pmtud meta l4proto icmpv6 icmpv6 type 2 icmpv6 code 0 ip6 daddr @no-pmtud-remote-node-ips-v6 counter drop +add rule inet ovn-kubernetes no-pmtud meta l4proto icmpv6 icmpv6 type 2 icmpv6 code 0 ip6 daddr @remote-node-ips-v6 counter drop add chain inet ovn-kubernetes no-pmtud { type filter hook output priority 0 ; comment "Block egress needs frag/packet too big to remote k8s nodes" ; } -add set inet ovn-kubernetes no-pmtud-remote-node-ips-v4 { type ipv4_addr ; comment "Block egress ICMP needs frag to remote Kubernetes nodes" ; } -add set inet ovn-kubernetes no-pmtud-remote-node-ips-v6 { type ipv6_addr ; comment "Block egress ICMPv6 packet too big to remote Kubernetes nodes" ; } +add set inet ovn-kubernetes remote-node-ips-v4 { type ipv4_addr ; comment "Block egress ICMP needs frag to remote Kubernetes nodes" ; } +add set inet ovn-kubernetes remote-node-ips-v6 { type ipv6_addr ; comment "Block egress ICMPv6 packet too big to remote Kubernetes nodes" ; } ` var _ = Describe("Node", func() { @@ -806,7 +806,7 @@ var _ = Describe("Node", func() { cnnci := NewCommonNodeNetworkControllerInfo(kubeFakeClient, fakeClient.AdminPolicyRouteClient, wf, nil, nodeName, routeManager) nc = newDefaultNodeNetworkController(cnnci, stop, wg, routeManager, nil) nc.initRetryFrameworkForNode() - err = setupPMTUDNFTSets() + err = setupRemoteNodeNFTSets() Expect(err).NotTo(HaveOccurred()) err = setupPMTUDNFTChain() Expect(err).NotTo(HaveOccurred()) @@ -830,7 +830,7 @@ var _ = Describe("Node", func() { err = nc.WatchNodes() Expect(err).NotTo(HaveOccurred()) nftRules := v4PMTUDNFTRules + ` -add element inet ovn-kubernetes no-pmtud-remote-node-ips-v4 { 169.254.254.61 } +add element inet ovn-kubernetes remote-node-ips-v4 { 169.254.254.61 } ` err = nodenft.MatchNFTRules(nftRules, nft.Dump()) Expect(err).NotTo(HaveOccurred()) @@ -911,7 +911,7 @@ add element inet ovn-kubernetes no-pmtud-remote-node-ips-v4 { 169.254.254.61 } cnnci := NewCommonNodeNetworkControllerInfo(kubeFakeClient, fakeClient.AdminPolicyRouteClient, wf, nil, nodeName, routeManager) nc = newDefaultNodeNetworkController(cnnci, stop, wg, routeManager, nil) nc.initRetryFrameworkForNode() - err = setupPMTUDNFTSets() + err = setupRemoteNodeNFTSets() Expect(err).NotTo(HaveOccurred()) err = setupPMTUDNFTChain() Expect(err).NotTo(HaveOccurred()) @@ -935,7 +935,7 @@ add element inet ovn-kubernetes no-pmtud-remote-node-ips-v4 { 169.254.254.61 } err = nc.WatchNodes() Expect(err).NotTo(HaveOccurred()) nftRules := v4PMTUDNFTRules + ` -add element inet ovn-kubernetes no-pmtud-remote-node-ips-v4 { 169.254.253.61 } +add element inet ovn-kubernetes remote-node-ips-v4 { 169.254.253.61 } ` err = nodenft.MatchNFTRules(nftRules, nft.Dump()) Expect(err).NotTo(HaveOccurred()) @@ -1058,7 +1058,7 @@ add element inet ovn-kubernetes no-pmtud-remote-node-ips-v4 { 169.254.253.61 } cnnci := NewCommonNodeNetworkControllerInfo(kubeFakeClient, fakeClient.AdminPolicyRouteClient, wf, nil, nodeName, routeManager) nc = newDefaultNodeNetworkController(cnnci, stop, wg, routeManager, nil) nc.initRetryFrameworkForNode() - err = setupPMTUDNFTSets() + err = setupRemoteNodeNFTSets() Expect(err).NotTo(HaveOccurred()) err = setupPMTUDNFTChain() Expect(err).NotTo(HaveOccurred()) @@ -1082,7 +1082,7 @@ add element inet ovn-kubernetes no-pmtud-remote-node-ips-v4 { 169.254.253.61 } err = nc.WatchNodes() Expect(err).NotTo(HaveOccurred()) nftRules := v6PMTUDNFTRules + ` -add element inet ovn-kubernetes no-pmtud-remote-node-ips-v6 { 2001:db8:1::4 } +add element inet ovn-kubernetes remote-node-ips-v6 { 2001:db8:1::4 } ` err = nodenft.MatchNFTRules(nftRules, nft.Dump()) Expect(err).NotTo(HaveOccurred()) @@ -1162,7 +1162,7 @@ add element inet ovn-kubernetes no-pmtud-remote-node-ips-v6 { 2001:db8:1::4 } cnnci := NewCommonNodeNetworkControllerInfo(kubeFakeClient, fakeClient.AdminPolicyRouteClient, wf, nil, nodeName, routeManager) nc = newDefaultNodeNetworkController(cnnci, stop, wg, routeManager, nil) nc.initRetryFrameworkForNode() - err = setupPMTUDNFTSets() + err = setupRemoteNodeNFTSets() Expect(err).NotTo(HaveOccurred()) err = setupPMTUDNFTChain() Expect(err).NotTo(HaveOccurred()) @@ -1186,7 +1186,7 @@ add element inet ovn-kubernetes no-pmtud-remote-node-ips-v6 { 2001:db8:1::4 } err = nc.WatchNodes() Expect(err).NotTo(HaveOccurred()) nftRules := v6PMTUDNFTRules + ` -add element inet ovn-kubernetes no-pmtud-remote-node-ips-v6 { 2002:db8:1::4 } +add element inet ovn-kubernetes remote-node-ips-v6 { 2002:db8:1::4 } ` err = nodenft.MatchNFTRules(nftRules, nft.Dump()) Expect(err).NotTo(HaveOccurred()) @@ -1323,7 +1323,7 @@ add element inet ovn-kubernetes no-pmtud-remote-node-ips-v6 { 2002:db8:1::4 } cnnci := NewCommonNodeNetworkControllerInfo(kubeFakeClient, fakeClient.AdminPolicyRouteClient, wf, nil, nodeName, routeManager) nc = newDefaultNodeNetworkController(cnnci, stop, wg, routeManager, nil) nc.initRetryFrameworkForNode() - err = setupPMTUDNFTSets() + err = setupRemoteNodeNFTSets() Expect(err).NotTo(HaveOccurred()) err = setupPMTUDNFTChain() Expect(err).NotTo(HaveOccurred()) @@ -1444,7 +1444,7 @@ add element inet ovn-kubernetes no-pmtud-remote-node-ips-v6 { 2002:db8:1::4 } cnnci := NewCommonNodeNetworkControllerInfo(kubeFakeClient, fakeClient.AdminPolicyRouteClient, wf, nil, nodeName, routeManager) nc = newDefaultNodeNetworkController(cnnci, stop, wg, routeManager, nil) nc.initRetryFrameworkForNode() - err = setupPMTUDNFTSets() + err = setupRemoteNodeNFTSets() Expect(err).NotTo(HaveOccurred()) err = setupPMTUDNFTChain() Expect(err).NotTo(HaveOccurred()) diff --git a/go-controller/pkg/node/node_nftables.go b/go-controller/pkg/node/node_nftables.go index e52a8970a4..ca4afc9ac2 100644 --- a/go-controller/pkg/node/node_nftables.go +++ b/go-controller/pkg/node/node_nftables.go @@ -13,8 +13,8 @@ import ( const nftPMTUDChain = "no-pmtud" -// setupPMTUDNFTSets sets up the NFT sets that contain remote Kubernetes node IPs -func setupPMTUDNFTSets() error { +// setupRemoteNodeNFTSets sets up the NFT sets that contain remote Kubernetes node IPs +func setupRemoteNodeNFTSets() error { nft, err := nodenft.GetNFTablesHelper() if err != nil { return fmt.Errorf("failed to get nftables helper: %w", err) @@ -22,12 +22,12 @@ func setupPMTUDNFTSets() error { tx := nft.NewTransaction() tx.Add(&knftables.Set{ - Name: types.NFTNoPMTUDRemoteNodeIPsv4, + Name: types.NFTRemoteNodeIPsv4, Comment: knftables.PtrTo("Block egress ICMP needs frag to remote Kubernetes nodes"), Type: "ipv4_addr", }) tx.Add(&knftables.Set{ - Name: types.NFTNoPMTUDRemoteNodeIPsv6, + Name: types.NFTRemoteNodeIPsv6, Comment: knftables.PtrTo("Block egress ICMPv6 packet too big to remote Kubernetes nodes"), Type: "ipv6_addr", }) @@ -68,7 +68,7 @@ func setupPMTUDNFTChain() error { tx.Add(&knftables.Rule{ Chain: nftPMTUDChain, Rule: knftables.Concat( - "ip daddr @"+types.NFTNoPMTUDRemoteNodeIPsv4, + "ip daddr @"+types.NFTRemoteNodeIPsv4, "meta l4proto icmp", "icmp type 3", // type 3 == Destination Unreachable "icmp code 4", // code 4 indicates fragmentation needed @@ -85,7 +85,7 @@ func setupPMTUDNFTChain() error { "meta l4proto icmpv6", // match on ICMPv6 packets "icmpv6 type 2", // type 2 == Packet Too Big (PMTUD) "icmpv6 code 0", // code 0 for that message - "ip6 daddr @"+types.NFTNoPMTUDRemoteNodeIPsv6, + "ip6 daddr @"+types.NFTRemoteNodeIPsv6, counterIfDebug, "drop", // drop the packet ), diff --git a/go-controller/pkg/types/const.go b/go-controller/pkg/types/const.go index 8ba7269cad..523da8e27b 100644 --- a/go-controller/pkg/types/const.go +++ b/go-controller/pkg/types/const.go @@ -312,13 +312,13 @@ const ( // CUDNPrefix of all CUDN network names CUDNPrefix = "cluster_udn_" - // NFTNoPMTUDRemoteNodeIPsv4 is a set used to track remote node IPs that do not belong to + // NFTRemoteNodeIPsv4 is a set used to track remote node v4IPs that do not belong to // the local node's subnet. - NFTNoPMTUDRemoteNodeIPsv4 = "no-pmtud-remote-node-ips-v4" + NFTRemoteNodeIPsv4 = "remote-node-ips-v4" - // NFTNoPMTUDRemoteNodeIPsv6 is a set used to track remote node IPs that do not belong to + // NFTRemoteNodeIPsv6 is a set used to track remote node v6IPs that do not belong to // the local node's subnet. - NFTNoPMTUDRemoteNodeIPsv6 = "no-pmtud-remote-node-ips-v6" + NFTRemoteNodeIPsv6 = "remote-node-ips-v6" // Metrics MetricOvnkubeNamespace = "ovnkube" From 04d48c314db6568287855f6d24cec14c9347e7f6 Mon Sep 17 00:00:00 2001 From: Surya Seetharaman Date: Wed, 9 Jul 2025 11:38:57 +0200 Subject: [PATCH 011/115] BGP, default network, LGW: Conditionally Masquerade This commit is valid only for default networks as mentioned in title. It's because unlike in UDNs where we do cSNATs in OVN on router at the edge before it leaves to node, for CDN everything happens on the node side already - so we can leverage the nodeIP masquerade bits. if network is advertised: chain ovn-kube-pod-subnet-masq { ip saddr 10.244.2.0/24 ip daddr @remote-node-ips-v4 masquerade ip6 saddr fd00:10:244:3::/64 ip6 daddr @remote-node-ips-v6 masquerade } else: chain ovn-kube-pod-subnet-masq { ip saddr 10.244.2.0/24 masquerade ip6 saddr fd00:10:244:3::/64 masquerade } Signed-off-by: Surya Seetharaman --- go-controller/pkg/node/gateway.go | 4 +-- go-controller/pkg/node/gateway_nftables.go | 33 ++++++++++++++++++---- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/go-controller/pkg/node/gateway.go b/go-controller/pkg/node/gateway.go index 7f11a0b813..fa812377e7 100644 --- a/go-controller/pkg/node/gateway.go +++ b/go-controller/pkg/node/gateway.go @@ -521,9 +521,9 @@ func (g *gateway) addAllServices() []error { func (g *gateway) updateSNATRules() error { subnets := util.IPsToNetworkIPs(g.nodeIPManager.mgmtPort.GetAddresses()...) - if g.GetDefaultPodNetworkAdvertised() || config.Gateway.Mode != config.GatewayModeLocal { + if config.Gateway.Mode != config.GatewayModeLocal { return delLocalGatewayPodSubnetNFTRules() } - return addLocalGatewayPodSubnetNFTRules(subnets...) + return addOrUpdateLocalGatewayPodSubnetNFTRules(g.GetDefaultPodNetworkAdvertised(), subnets...) } diff --git a/go-controller/pkg/node/gateway_nftables.go b/go-controller/pkg/node/gateway_nftables.go index c2de7aa5e7..71a4d23b9e 100644 --- a/go-controller/pkg/node/gateway_nftables.go +++ b/go-controller/pkg/node/gateway_nftables.go @@ -203,16 +203,32 @@ func getUDNNFTRules(service *corev1.Service, netConfig *bridgeconfig.BridgeUDNCo // ip saddr 10.244.0.0/24 masquerade // ip6 saddr fd00:10:244:1::/64 masquerade // } -func getLocalGatewayPodSubnetMasqueradeNFTRule(cidr *net.IPNet) (*knftables.Rule, error) { +// +// If isAdvertisedNetwork is true, masquerade only when destination matches remote node IPs. +// Rules look like: +// ip saddr 10.244.0.0/24 ip daddr @remote-node-ips-v4 masquerade +// ip6 saddr fd00:10:244:1::/64 ip6 daddr @remote-node-ips-v6 masquerade +func getLocalGatewayPodSubnetMasqueradeNFTRule(cidr *net.IPNet, isAdvertisedNetwork bool) (*knftables.Rule, error) { // Create the rule for masquerading traffic from the CIDR - ipPrefix := "ip" + var ipPrefix string + var remoteNodeSetName string if utilnet.IsIPv6CIDR(cidr) { ipPrefix = "ip6" + remoteNodeSetName = types.NFTRemoteNodeIPsv6 + } else { + ipPrefix = "ip" + remoteNodeSetName = types.NFTRemoteNodeIPsv4 } + // If network is advertised, only masquerade if destination is a remote node IP + var optionalDestRules []string + if isAdvertisedNetwork { + optionalDestRules = []string{ipPrefix, "daddr", "@", remoteNodeSetName} + } rule := &knftables.Rule{ Rule: knftables.Concat( ipPrefix, "saddr", cidr, + optionalDestRules, "masquerade", ), Chain: nftablesPodSubnetMasqChain, @@ -261,7 +277,7 @@ func getLocalGatewayNATNFTRules(cidrs ...*net.IPNet) ([]*knftables.Rule, error) rules = append(rules, masqRule) // Rule2: Pod subnet NAT rule for the pod subnet chain - podSubnetRule, err := getLocalGatewayPodSubnetMasqueradeNFTRule(cidr) + podSubnetRule, err := getLocalGatewayPodSubnetMasqueradeNFTRule(cidr, false) if err != nil { return nil, fmt.Errorf("failed to create pod subnet masquerade rule: %w", err) } @@ -421,9 +437,12 @@ func initLocalGatewayNFTNATRules(cidrs ...*net.IPNet) error { return nil } -// addLocalGatewayPodSubnetNFTRules adds nftables rules for pod subnet masquerading for multiple CIDRs +// addOrUpdateLocalGatewayPodSubnetNFTRules adds nftables rules for pod subnet masquerading for multiple CIDRs // These rules are added to the dedicated pod subnet masquerade chain. -func addLocalGatewayPodSubnetNFTRules(cidrs ...*net.IPNet) error { +// If the rules already exist, they are updated. +// If isAdvertisedNetwork is true, the masquerade rules also get a destination match +// that matches the remote node IP set. +func addOrUpdateLocalGatewayPodSubnetNFTRules(isAdvertisedNetwork bool, cidrs ...*net.IPNet) error { nft, err := nodenft.GetNFTablesHelper() if err != nil { return fmt.Errorf("failed to get nftables helper: %w", err) @@ -438,10 +457,12 @@ func addLocalGatewayPodSubnetNFTRules(cidrs ...*net.IPNet) error { tx.Add(podSubnetChain) // Flush the chain to remove all existing rules + // if network toggles between advertised and non-advertised, we need to flush the chain and re-add correct rules tx.Flush(podSubnetChain) + // Add the new rules for each CIDR for _, cidr := range cidrs { - rule, err := getLocalGatewayPodSubnetMasqueradeNFTRule(cidr) + rule, err := getLocalGatewayPodSubnetMasqueradeNFTRule(cidr, isAdvertisedNetwork) if err != nil { return fmt.Errorf("failed to create nftables rules for CIDR %s: %w", cidr.String(), err) } From 8a65723f1d90d2360c9a3f965e89eb124c026e3b Mon Sep 17 00:00:00 2001 From: Surya Seetharaman Date: Wed, 2 Jul 2025 11:16:52 +0200 Subject: [PATCH 012/115] Add E2E's for these traffic flows 1) remove the l2 failure limitation since we now use nodeIPs reply knows how to go back to src node since we have routes for that 2) add udn pod -> default network nodeport service (same and diff node) 3) add udn pod -> udn network nodeport service (same and diff node) - same network 4) add udn pod -> udn network nodeport service (same and diff node) - different network Signed-off-by: Surya Seetharaman Signed-off-by: Surya Seetharaman --- test/e2e/route_advertisements.go | 113 ++++++++++++++++++++++++------- 1 file changed, 90 insertions(+), 23 deletions(-) diff --git a/test/e2e/route_advertisements.go b/test/e2e/route_advertisements.go index f65dd60631..d46d0a9409 100644 --- a/test/e2e/route_advertisements.go +++ b/test/e2e/route_advertisements.go @@ -28,7 +28,6 @@ import ( "github.com/ovn-org/ovn-kubernetes/test/e2e/label" corev1 "k8s.io/api/core/v1" - v1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -626,7 +625,7 @@ var _ = ginkgo.DescribeTableSubtree("BGP: isolation between advertised networks" } // create host networked Pods - _, err := createPod(f, node.Name+"-hostnet-ep", node.Name, f.Namespace.Name, []string{}, map[string]string{}, func(p *v1.Pod) { + _, err := createPod(f, node.Name+"-hostnet-ep", node.Name, f.Namespace.Name, []string{}, map[string]string{}, func(p *corev1.Pod) { p.Spec.Containers[0].Args = args p.Spec.HostNetwork = true }) @@ -652,6 +651,7 @@ var _ = ginkgo.DescribeTableSubtree("BGP: isolation between advertised networks" svc.Spec.Ports = []corev1.ServicePort{{Port: 8080}} familyPolicy := corev1.IPFamilyPolicyPreferDualStack svc.Spec.IPFamilyPolicy = &familyPolicy + svc.Spec.Type = corev1.ServiceTypeNodePort svcNetA, err = f.ClientSet.CoreV1().Services(pod.Namespace).Create(context.Background(), svc, metav1.CreateOptions{}) gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -675,6 +675,7 @@ var _ = ginkgo.DescribeTableSubtree("BGP: isolation between advertised networks" svc.Name = fmt.Sprintf("service-default") svc.Namespace = "default" svc.Spec.Selector = pod.Labels + svc.Spec.Type = corev1.ServiceTypeNodePort svcNetDefault, err = f.ClientSet.CoreV1().Services(pod.Namespace).Create(context.Background(), svc, metav1.CreateOptions{}) gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -754,6 +755,7 @@ var _ = ginkgo.DescribeTableSubtree("BGP: isolation between advertised networks" } if svcNetDefault != nil { err = f.ClientSet.CoreV1().Services(svcNetDefault.Namespace).Delete(context.Background(), svcNetDefault.Name, metav1.DeleteOptions{}) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) svcNetDefault = nil } @@ -954,11 +956,11 @@ var _ = ginkgo.DescribeTableSubtree("BGP: isolation between advertised networks" // options [mss 1360,sackOK,TS val 3006752321 ecr 0,nop,wscale 7], length 0 // 10:59:55.352404 ovn-k8s-mp87 In ifindex 186 0a:58:5d:5d:01:01 ethertype IPv4 (0x0800), length 80: (tos 0x0, ttl 63, id 57264, // offset 0, flags [DF], proto TCP (6), length 60) - // 93.93.1.5.36363 > 172.18.0.2.25022: Flags [S], cksum 0xe0b7 (correct), seq 3879759281, win 65280, + // 169.154.169.12.36363 > 172.18.0.2.25022: Flags [S], cksum 0xe0b7 (correct), seq 3879759281, win 65280, // options [mss 1360,sackOK,TS val 3006752321 ecr 0,nop,wscale 7], length 0 // 10:59:55.352461 ovn-k8s-mp87 Out ifindex 186 0a:58:5d:5d:01:02 ethertype IPv4 (0x0800), length 60: (tos 0x0, ttl 64, id 0, // offset 0, flags [DF], proto TCP (6), length 40) - // 172.18.0.2.25022 > 93.93.1.5.36363: Flags [R.], cksum 0x609d (correct), seq 0, ack 3879759282, win 0, length 0 + // 172.18.0.2.25022 > 169.154.169.12.36363: Flags [R.], cksum 0x609d (correct), seq 0, ack 3879759282, win 0, length 0 // 10:59:55.352927 319594f193d4d_3 Out ifindex 191 0a:58:5d:5d:01:02 ethertype IPv4 (0x0800), length 60: (tos 0x0, ttl 64, id 0, // offset 0, flags [DF], proto TCP (6), length 40) // 172.18.0.2.25022 > 93.93.1.5.36363: Flags [R.], cksum 0x609d (correct), seq 0, ack 1, win 0, length 0 @@ -971,25 +973,90 @@ var _ = ginkgo.DescribeTableSubtree("BGP: isolation between advertised networks" node, err := f.ClientSet.CoreV1().Nodes().Get(context.TODO(), podsNetA[2].Spec.NodeName, metav1.GetOptions{}) framework.ExpectNoError(err) nodeIP := node.Status.Addresses[ipFamilyIndex].Address - errBool := false - out := "" - if cudnATemplate.Spec.Network.Topology == udnv1.NetworkTopologyLayer2 { - // FIXME: this should be removed once we add the SNAT for pod->node traffic - // We now permit asymmetric traffic on LGW. This prevents the issue from occurring with IPv6. - // However, for IPv4 LGW rp_filter is still blocking the replies. - // The situation is different on SGW as we don't allow asymmetric traffic at all, which is why IPv6 traffic fails there too. - if ipFamilyIndex == ipFamilyV4 || !isLocalGWModeEnabled() { - // FIXME: fix assymmetry in L2 UDNs - // bad behaviour: packet is coming from other node -> entering eth0 -> bretho and here kernel drops the packet since - // rp_filter is set to 1 in breth0 and there is an iprule that sends the packet to mpX interface so kernel sees the packet - // having return path different from the incoming interface. - // The SNAT to nodeIP should fix this. - // this causes curl timeout with code 28 - errBool = true - out = curlConnectionTimeoutCode - } - } - return clientPod.Name, clientPod.Namespace, net.JoinHostPort(nodeIP, fmt.Sprint(hostNetworkPort)) + "/hostname", out, errBool + + clientNode, err := f.ClientSet.CoreV1().Nodes().Get(context.TODO(), clientPod.Spec.NodeName, metav1.GetOptions{}) + framework.ExpectNoError(err) + clientNodeIP := clientNode.Status.Addresses[ipFamilyIndex].Address + // pod -> node traffic should use the node's IP as the source for advertised UDNs. + return clientPod.Name, clientPod.Namespace, net.JoinHostPort(nodeIP, fmt.Sprint(hostNetworkPort)) + "/clientip", clientNodeIP, false + }), + ginkgo.Entry("UDN pod to the same node nodeport service in default network should work (should it? :)...)", + func(ipFamilyIndex int) (clientName string, clientNamespace string, dst string, expectedOutput string, expectErr bool) { + clientPod := podsNetA[0] + // podsNetA[0] is on nodes[0]. We need the same node. Let's hit the nodeport on nodes[0]. + node, err := f.ClientSet.CoreV1().Nodes().Get(context.TODO(), nodes.Items[0].Name, metav1.GetOptions{}) + framework.ExpectNoError(err) + nodeIP := node.Status.Addresses[ipFamilyIndex].Address + nodePort := svcNetDefault.Spec.Ports[0].NodePort + + return clientPod.Name, clientPod.Namespace, net.JoinHostPort(nodeIP, fmt.Sprint(nodePort)) + "/hostname", "", false + }), + ginkgo.Entry("UDN pod to a different node nodeport service in default network should work", + func(ipFamilyIndex int) (clientName string, clientNamespace string, dst string, expectedOutput string, expectErr bool) { + clientPod := podsNetA[0] + // podsNetA[0] is on nodes[0]. We need a different node. podNetDefault is on nodes[1]. + // The service is backed by podNetDefault. Let's hit the nodeport on nodes[2]. + node, err := f.ClientSet.CoreV1().Nodes().Get(context.TODO(), nodes.Items[2].Name, metav1.GetOptions{}) + framework.ExpectNoError(err) + nodeIP := node.Status.Addresses[ipFamilyIndex].Address + nodePort := svcNetDefault.Spec.Ports[0].NodePort + + return clientPod.Name, clientPod.Namespace, net.JoinHostPort(nodeIP, fmt.Sprint(nodePort)) + "/hostname", "", false + }), + ginkgo.Entry("UDN pod to the same node nodeport service in same UDN network should work", + func(ipFamilyIndex int) (clientName string, clientNamespace string, dst string, expectedOutput string, expectErr bool) { + clientPod := podsNetA[0] + // The service is backed by pods in podsNetA. + // We want to hit the nodeport on the same node. + // client is on nodes[0]. Let's hit nodeport on nodes[0]. + node, err := f.ClientSet.CoreV1().Nodes().Get(context.TODO(), nodes.Items[0].Name, metav1.GetOptions{}) + framework.ExpectNoError(err) + nodeIP := node.Status.Addresses[ipFamilyIndex].Address + nodePort := svcNetA.Spec.Ports[0].NodePort + + // The service can be backed by any of the pods in podsNetA, so we can't reliably check the output hostname. + // Just check that the connection is successful. + return clientPod.Name, clientPod.Namespace, net.JoinHostPort(nodeIP, fmt.Sprint(nodePort)) + "/hostname", "", false + }), + ginkgo.Entry("UDN pod to a different node nodeport service in same UDN network should work", + func(ipFamilyIndex int) (clientName string, clientNamespace string, dst string, expectedOutput string, expectErr bool) { + clientPod := podsNetA[0] + // The service is backed by pods in podsNetA. + // We want to hit the nodeport on a different node. + // client is on nodes[0]. Let's hit nodeport on nodes[2]. + node, err := f.ClientSet.CoreV1().Nodes().Get(context.TODO(), nodes.Items[2].Name, metav1.GetOptions{}) + framework.ExpectNoError(err) + nodeIP := node.Status.Addresses[ipFamilyIndex].Address + nodePort := svcNetA.Spec.Ports[0].NodePort + + // sourceIP will be joinSubnetIP for nodeports, so only using hostname endpoint + return clientPod.Name, clientPod.Namespace, net.JoinHostPort(nodeIP, fmt.Sprint(nodePort)) + "/hostname", "", false + }), + ginkgo.Entry("UDN pod to the same node nodeport service in different UDN network should not work", + // FIXME: This test should work: https://github.com/ovn-kubernetes/ovn-kubernetes/issues/5419 + func(ipFamilyIndex int) (clientName string, clientNamespace string, dst string, expectedOutput string, expectErr bool) { + clientPod := podsNetA[0] + node, err := f.ClientSet.CoreV1().Nodes().Get(context.TODO(), nodes.Items[0].Name, metav1.GetOptions{}) + framework.ExpectNoError(err) + nodeIP := node.Status.Addresses[ipFamilyIndex].Address + nodePort := svcNetB.Spec.Ports[0].NodePort + + // sourceIP will be joinSubnetIP for nodeports, so only using hostname endpoint + return clientPod.Name, clientPod.Namespace, net.JoinHostPort(nodeIP, fmt.Sprint(nodePort)) + "/hostname", curlConnectionTimeoutCode, true + }), + ginkgo.Entry("UDN pod to a different node nodeport service in different UDN network should work", + func(ipFamilyIndex int) (clientName string, clientNamespace string, dst string, expectedOutput string, expectErr bool) { + clientPod := podsNetA[0] + // The service is backed by podNetB. + // We want to hit the nodeport on a different node from the client. + // client is on nodes[0]. Let's hit nodeport on nodes[2]. + node, err := f.ClientSet.CoreV1().Nodes().Get(context.TODO(), nodes.Items[2].Name, metav1.GetOptions{}) + framework.ExpectNoError(err) + nodeIP := node.Status.Addresses[ipFamilyIndex].Address + nodePort := svcNetB.Spec.Ports[0].NodePort + + // sourceIP will be joinSubnetIP for nodeports, so only using hostname endpoint + return clientPod.Name, clientPod.Namespace, net.JoinHostPort(nodeIP, fmt.Sprint(nodePort)) + "/hostname", "", false }), ) From 10ea4ab4a2222577f54b03d84491c6abd7e17d23 Mon Sep 17 00:00:00 2001 From: Surya Seetharaman Date: Fri, 11 Jul 2025 14:01:33 +0200 Subject: [PATCH 013/115] Add masqueradeIP flows back for advertised networks in breth0 In the previous commits we added SNATing to nodeIP for the following traffic flows: pod -> nodes pod -> nodeports when pods are part of advertised networks. Prior to SNATing to nodeIPs they are SNATed at the ovn_cluster_router to masqueradeIP before being sent into the host. In commit https://github.com/ovn-kubernetes/ovn-kubernetes/commit/75dd73fb645bff6c30e8c08c9b7f711d82996601 we had converted all UDN flows that matched on masqueradeIP as the source on breth0 for UDN pods to services traffic flow to instead match on the podsubnets. However given we have pod to node and pod to nodeport traffic flows using masqueradeIP as the SNAT we need to now re-add the masqueradeIP flows as well to ensure that nodeports isolation between UDNs work correctly. Before this commit: In LGW/SGW flow is: UDN pod -> samenodeIP:nodeport in default network -> SNATed to masqueradeIP of that UDN -> sent to host -> SNATed to clusterIP -> hits the default flow in table=2 in br-ex: cookie=0xdeff105, duration=15690.053s, table=2, n_packets=0, n_bytes=0, idle_age=15690, priority=100 actions=mod_dl_dst:6e:4d:97:c0:3c:97,output:2 and sends to patch port of default network and this traffic starts working when it shouldn't. (I mean eventually we want this to work, see https://github.com/ovn-kubernetes/ovn-kubernetes/issues/5410 but that's a future issue - outside my PR's scope) In case of L3 UDN advertised pod -> nodeport service in default or other UDN network: https://github.com/ovn-kubernetes/ovn-kubernetes/pull/4705/commits/d63887ed167da260d3f26c71ec06e520d89a4b0f is the commit where we added logic to match on srcIP of the traffic and accordingly route it into the respective UDN patchports. So there we use the masqueradeIP of a particular UDN to determine what the source of the traffic was and route it into that particular UDN's patchport where it would backhole if there was no matching clusterIP NAT entry there, and this is how isolation was guaranteed. Recently this was changed to a hard drop: https://github.com/ovn-kubernetes/ovn-kubernetes/pull/5351/commits/dcc403c1ddf11e30e6990699616405f6dc47dd71 For l2 topology the logic is same as above for clusterIPs but for nodeports the GR itself drops the packets destined towards the other networks as there is no LB entry present on the GR as the destination IP is that of the router itself. That's how isolation works there: sample trace: next; 10. ls_out_apply_port_sec (northd.c:6039): 1, priority 0, uuid 2aa6ebd5 output; /* output to "stor-cluster_udn_tenant.blue.network_ovn_layer2_switch", type "l3gateway" */ ingress(dp="GR_cluster_udn_tenant.blue.network_ovn-worker2", inport="rtos-cluster_udn_tenant.blue.network_ovn_layer2_switch") ----------------------------------------------------------------------------------------------------------------------------- 0. lr_in_admission (northd.c:13232): eth.dst == 0a:58:64:41:00:03 && inport == "rtos-cluster_udn_tenant.blue.network_ovn_layer2_switch", priority 50, uuid 7f9af183 reg9[1] = check_pkt_larger(1414); xreg0[0..47] = 0a:58:64:41:00:03; next; 1. lr_in_lookup_neighbor (northd.c:13420): 1, priority 0, uuid d2672052 reg9[2] = 1; next; 2. lr_in_learn_neighbor (northd.c:13430): reg9[2] == 1 || reg9[3] == 0, priority 100, uuid 84ca0ef4 mac_cache_use; next; 3. lr_in_ip_input (northd.c:12824): ip4.dst == {172.18.0.4}, priority 60, uuid ea41c4e7 drop; Without this fix: [FAIL] BGP: isolation between advertised networks Layer3 connectivity between networks [It] pod in the UDN should not be able to access a default network service the above test will work in LGW when it should not work like is the case for non-advertised UDNs. This commit adds back the masqueradeIP flow as well for advertised networks that drops all packets that didn't get routed on the higher priority pkt_mark flows at 250. when 2 UDNs are advertised: this PR added back these two flows with masqueradeIP match: cookie=0xdeff105, duration=127.593s, table=2, n_packets=0, n_bytes=0, priority=200,ip,nw_src=169.254.0.12 actions=drop cookie=0xdeff105, duration=127.534s, table=2, n_packets=0, n_bytes=0, priority=200,ip,nw_src=169.254.0.14 actions=drop Signed-off-by: Surya Seetharaman --- .../pkg/node/bridgeconfig/bridgeflows.go | 25 +++++++++++-------- go-controller/pkg/node/gateway_udn_test.go | 6 +++-- test/e2e/route_advertisements.go | 5 ++-- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/go-controller/pkg/node/bridgeconfig/bridgeflows.go b/go-controller/pkg/node/bridgeconfig/bridgeflows.go index d03b88c8de..200c1540ec 100644 --- a/go-controller/pkg/node/bridgeconfig/bridgeflows.go +++ b/go-controller/pkg/node/bridgeconfig/bridgeflows.go @@ -349,13 +349,12 @@ func (b *BridgeConfiguration) flowsForDefaultBridge(extraIPs []net.IP) ([]string bridgeMacAddress, mod_vlan_id, defaultNetConfig.OfPortPatch)) // table 2, priority 200, dispatch from UDN -> Host -> OVN. These packets have - // already been SNATed to the UDN's masq IP or have been marked with the UDN's packet mark. + // already been SNATed to the UDN's masquerade IP or have been marked with the UDN's packet mark. if config.IPv4Mode { for _, netConfig := range b.patchedNetConfigs() { if netConfig.IsDefaultNetwork() { continue } - srcIPOrSubnet := netConfig.V4MasqIPs.ManagementPort.IP.String() if util.IsRouteAdvertisementsEnabled() && netConfig.Advertised.Load() { var udnAdvertisedSubnets []*net.IPNet for _, clusterEntry := range netConfig.Subnets { @@ -368,9 +367,14 @@ func (b *BridgeConfiguration) flowsForDefaultBridge(extraIPs []net.IP) ([]string klog.Infof("Unable to determine IPV4 UDN subnet for the provided family isIPV6: %v", err) continue } - - // Use the filtered subnets for the flow compute instead of the masqueradeIP - srcIPOrSubnet = matchingIPFamilySubnet.String() + // In addition to the masqueradeIP based flows, we also need the podsubnet based flows for + // advertised networks since UDN pod to clusterIP is unSNATed and we need this traffic to be taken into + // the correct patch port of it's own network where it's a deadend if the clusterIP is not part of + // that UDN network and works if it is part of the UDN network. + dftFlows = append(dftFlows, + fmt.Sprintf("cookie=%s, priority=200, table=2, ip, ip_src=%s, "+ + "actions=drop", + nodetypes.DefaultOpenFlowCookie, matchingIPFamilySubnet.String())) } // Drop traffic coming from the masquerade IP or the UDN subnet(for advertised UDNs) to ensure that // isolation between networks is enforced. This handles the case where a pod on the UDN subnet is sending traffic to @@ -378,7 +382,7 @@ func (b *BridgeConfiguration) flowsForDefaultBridge(extraIPs []net.IP) ([]string dftFlows = append(dftFlows, fmt.Sprintf("cookie=%s, priority=200, table=2, ip, ip_src=%s, "+ "actions=drop", - nodetypes.DefaultOpenFlowCookie, srcIPOrSubnet)) + nodetypes.DefaultOpenFlowCookie, netConfig.V4MasqIPs.ManagementPort.IP.String())) dftFlows = append(dftFlows, fmt.Sprintf("cookie=%s, priority=250, table=2, ip, pkt_mark=%s, "+ @@ -393,7 +397,6 @@ func (b *BridgeConfiguration) flowsForDefaultBridge(extraIPs []net.IP) ([]string if netConfig.IsDefaultNetwork() { continue } - srcIPOrSubnet := netConfig.V6MasqIPs.ManagementPort.IP.String() if util.IsRouteAdvertisementsEnabled() && netConfig.Advertised.Load() { var udnAdvertisedSubnets []*net.IPNet for _, clusterEntry := range netConfig.Subnets { @@ -407,13 +410,15 @@ func (b *BridgeConfiguration) flowsForDefaultBridge(extraIPs []net.IP) ([]string continue } - // Use the filtered subnets for the flow compute instead of the masqueradeIP - srcIPOrSubnet = matchingIPFamilySubnet.String() + dftFlows = append(dftFlows, + fmt.Sprintf("cookie=%s, priority=200, table=2, ip6, ipv6_src=%s, "+ + "actions=drop", + nodetypes.DefaultOpenFlowCookie, matchingIPFamilySubnet.String())) } dftFlows = append(dftFlows, fmt.Sprintf("cookie=%s, priority=200, table=2, ip6, ipv6_src=%s, "+ "actions=drop", - nodetypes.DefaultOpenFlowCookie, srcIPOrSubnet)) + nodetypes.DefaultOpenFlowCookie, netConfig.V6MasqIPs.ManagementPort.IP.String())) dftFlows = append(dftFlows, fmt.Sprintf("cookie=%s, priority=250, table=2, ip6, pkt_mark=%s, "+ "actions=set_field:%s->eth_dst,output:%s", diff --git a/go-controller/pkg/node/gateway_udn_test.go b/go-controller/pkg/node/gateway_udn_test.go index 0ab0bf573b..bd05aacd57 100644 --- a/go-controller/pkg/node/gateway_udn_test.go +++ b/go-controller/pkg/node/gateway_udn_test.go @@ -1143,7 +1143,7 @@ var _ = Describe("UserDefinedNetworkGateway", func() { Expect(udnGateway.AddNetwork()).To(Succeed()) flowMap = udnGateway.gateway.openflowManager.flowCache - Expect(flowMap["DEFAULT"]).To(HaveLen(69)) // 18 UDN Flows and 5 advertisedUDN flows are added by default + Expect(flowMap["DEFAULT"]).To(HaveLen(71)) // 18 UDN Flows, 5 advertisedUDN flows, and 2 packet mark flows (IPv4+IPv6) are added by default Expect(udnGateway.openflowManager.defaultBridge.GetNetConfigLen()).To(Equal(2)) // default network + UDN network defaultUdnConfig := udnGateway.openflowManager.defaultBridge.GetNetworkConfig("default") bridgeUdnConfig := udnGateway.openflowManager.defaultBridge.GetNetworkConfig("bluenet") @@ -1166,7 +1166,9 @@ var _ = Describe("UserDefinedNetworkGateway", func() { // Check flows for default network service CIDR. bridgeconfig.CheckDefaultSvcIsolationOVSFlows(flowMap["DEFAULT"], defaultUdnConfig, ofPortHost, bridgeMAC, svcCIDR) - // Expect exactly one flow per advertised UDN for table 2 and table 0 for service isolation. + // Expect exactly two flow per advertised UDN for table 2 and table 0 for service isolation. + // but one of the flows used by advertised UDNs is already tracked and used by default UDNs hence not + // counted here but in the check above for default svc isolation flows. bridgeconfig.CheckAdvertisedUDNSvcIsolationOVSFlows(flowMap["DEFAULT"], bridgeUdnConfig, "bluenet", svcCIDR, 2) } diff --git a/test/e2e/route_advertisements.go b/test/e2e/route_advertisements.go index d46d0a9409..026dfc5901 100644 --- a/test/e2e/route_advertisements.go +++ b/test/e2e/route_advertisements.go @@ -980,7 +980,8 @@ var _ = ginkgo.DescribeTableSubtree("BGP: isolation between advertised networks" // pod -> node traffic should use the node's IP as the source for advertised UDNs. return clientPod.Name, clientPod.Namespace, net.JoinHostPort(nodeIP, fmt.Sprint(hostNetworkPort)) + "/clientip", clientNodeIP, false }), - ginkgo.Entry("UDN pod to the same node nodeport service in default network should work (should it? :)...)", + ginkgo.Entry("UDN pod to the same node nodeport service in default network should not work", + // FIXME: https://github.com/ovn-kubernetes/ovn-kubernetes/issues/5410 func(ipFamilyIndex int) (clientName string, clientNamespace string, dst string, expectedOutput string, expectErr bool) { clientPod := podsNetA[0] // podsNetA[0] is on nodes[0]. We need the same node. Let's hit the nodeport on nodes[0]. @@ -989,7 +990,7 @@ var _ = ginkgo.DescribeTableSubtree("BGP: isolation between advertised networks" nodeIP := node.Status.Addresses[ipFamilyIndex].Address nodePort := svcNetDefault.Spec.Ports[0].NodePort - return clientPod.Name, clientPod.Namespace, net.JoinHostPort(nodeIP, fmt.Sprint(nodePort)) + "/hostname", "", false + return clientPod.Name, clientPod.Namespace, net.JoinHostPort(nodeIP, fmt.Sprint(nodePort)) + "/hostname", curlConnectionTimeoutCode, true }), ginkgo.Entry("UDN pod to a different node nodeport service in default network should work", func(ipFamilyIndex int) (clientName string, clientNamespace string, dst string, expectedOutput string, expectErr bool) { From 8f5b3d4688db4ba150431a41c49f9a5e569d8228 Mon Sep 17 00:00:00 2001 From: Surya Seetharaman Date: Sat, 12 Jul 2025 21:12:52 +0200 Subject: [PATCH 014/115] Change priority of ovn-kube-local-gw-masq to 101 Currently there are two bugs around using priority 100 for ovn-kube-local-gw-masq chain. EgressIPs multinic rules are still in legacy IPT: [0:0] -A OVN-KUBE-EGRESS-IP-MULTI-NIC -s 10.244.2.6/32 -o eth1 -j SNAT --to-source 10.10.10.105 [0:0] -A OVN-KUBE-EGRESS-IP-MULTI-NIC -s 10.244.0.3/32 -o eth1 -j SNAT --to-source 10.10.10.105 [1:60] -A OVN-KUBE-EGRESS-IP-MULTI-NIC -s 10.244.1.3/32 -o eth1 -j SNAT --to-source 10.10.10.105 and in netfilter the priority of NAT POSTROUTNG HOOK is 100 and not configurable. NF_IP_PRI_NAT_SRC in netfilter and for NFTables its the same value 100 for NAT POSTROUTING hook and its called "srcnat" in knftables and set to 100. and this is the priority used by egress service feature since that is already converted to NFT: chain egress-services { type nat hook postrouting priority srcnat; policy accept; meta mark 0x000003f0 return comment "DoNotSNAT" snat ip to ip saddr map @egress-service-snat-v4 snat ip6 to ip6 saddr map @egress-service-snat-v6 } and now that we have converted POSTROUTING rules for local-gw as well to NFT, those rules were already at priority 100. Unlike IPT rules where we could jump to EIP and ESVC chains before masquerade rules got hit, here those chains in NFT are all parallel at same priority 100 and we don't know which one will be hit first. Hence we need to change the priority of ovn-kube-local-gw-masq so that EIP/ESVC rules are hit before the default masquerade rules W/O this change EIP/ESVC tests fail in CI Signed-off-by: Surya Seetharaman --- go-controller/pkg/node/gateway_init_linux_test.go | 2 +- go-controller/pkg/node/gateway_nftables.go | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/go-controller/pkg/node/gateway_init_linux_test.go b/go-controller/pkg/node/gateway_init_linux_test.go index 9bc0cc5401..06fe88aace 100644 --- a/go-controller/pkg/node/gateway_init_linux_test.go +++ b/go-controller/pkg/node/gateway_init_linux_test.go @@ -87,7 +87,7 @@ add rule inet ovn-kubernetes ovn-kube-local-gw-masq jump ovn-kube-udn-masq const baseLGWNFTablesRules = ` add rule inet ovn-kubernetes ovn-kube-local-gw-masq ip saddr 169.254.169.1 masquerade -add chain inet ovn-kubernetes ovn-kube-local-gw-masq { type nat hook postrouting priority 100 ; comment "OVN local gateway masquerade" ; } +add chain inet ovn-kubernetes ovn-kube-local-gw-masq { type nat hook postrouting priority 101 ; comment "OVN local gateway masquerade" ; } add rule inet ovn-kubernetes ovn-kube-local-gw-masq jump ovn-kube-pod-subnet-masq add rule inet ovn-kubernetes ovn-kube-pod-subnet-masq ip saddr 10.1.1.0/24 masquerade add chain inet ovn-kubernetes ovn-kube-pod-subnet-masq diff --git a/go-controller/pkg/node/gateway_nftables.go b/go-controller/pkg/node/gateway_nftables.go index 71a4d23b9e..b38f2baebb 100644 --- a/go-controller/pkg/node/gateway_nftables.go +++ b/go-controller/pkg/node/gateway_nftables.go @@ -366,12 +366,18 @@ func initLocalGatewayNFTNATRules(cidrs ...*net.IPNet) error { tx := nft.NewTransaction() // Create main local gateway masquerade chain + // Use priority 101 instead of defaultknftables.SNATPriority (100) to ensure + // iptables egress IP rules in OVN-KUBE-EGRESS-IP-MULTI-NIC chain run first + // this also ensure for egress-services, the + // chain egress-services { + // type nat hook postrouting priority srcnat; policy accept; + // is called before the local gateway masquerade chain localGwMasqChain := &knftables.Chain{ Name: nftablesLocalGatewayMasqChain, Comment: knftables.PtrTo("OVN local gateway masquerade"), Type: knftables.PtrTo(knftables.NATType), Hook: knftables.PtrTo(knftables.PostroutingHook), - Priority: knftables.PtrTo(knftables.SNATPriority), + Priority: knftables.PtrTo(knftables.BaseChainPriority("101")), } tx.Add(localGwMasqChain) From 659010cfd44af66c071e347ed1e2051494fec68e Mon Sep 17 00:00:00 2001 From: Surya Seetharaman Date: Mon, 21 Jul 2025 09:59:41 +0200 Subject: [PATCH 015/115] Add all remote nodeIPs for the PMTUD/BGP remote node NFT set Prior to this change, the remote PMTUD address sets were only considering the primary IP of the node. While that was OK for PMTUD use case perhaps but for BGP now that we reuse this address set in NFT we need to consider all the IPs on the remote nodes. So this commit changes code from using node internal IPs to using the HostCIDRs annotation Signed-off-by: Surya Seetharaman --- .../node/default_node_network_controller.go | 90 ++++++++++--------- .../default_node_network_controller_test.go | 24 +++++ go-controller/pkg/node/obj_retry_node.go | 53 ++++++----- 3 files changed, 105 insertions(+), 62 deletions(-) diff --git a/go-controller/pkg/node/default_node_network_controller.go b/go-controller/pkg/node/default_node_network_controller.go index db7d26802d..47ba8f6262 100644 --- a/go-controller/pkg/node/default_node_network_controller.go +++ b/go-controller/pkg/node/default_node_network_controller.go @@ -1515,23 +1515,32 @@ func (nc *DefaultNodeNetworkController) WatchNodes() error { func (nc *DefaultNodeNetworkController) addOrUpdateNode(node *corev1.Node) error { var nftElems []*knftables.Element var addrs []string - for _, address := range node.Status.Addresses { - if address.Type != corev1.NodeInternalIP { - continue - } - nodeIP := net.ParseIP(address.Address) - if nodeIP == nil { - continue - } + // Use GetNodeAddresses to get all node IPs (including current node for openflow) + ipsv4, ipsv6, err := util.GetNodeAddresses(config.IPv4Mode, config.IPv6Mode, node) + if err != nil { + return fmt.Errorf("failed to get node addresses for node %q: %w", node.Name, err) + } + + // Process IPv4 addresses + for _, nodeIP := range ipsv4 { addrs = append(addrs, nodeIP.String()) klog.Infof("Adding remote node %q, IP: %s to PMTUD blocking rules", node.Name, nodeIP) - if utilnet.IsIPv4(nodeIP) { + // Only add to nftables if this is remote node + if node.Name != nc.name { nftElems = append(nftElems, &knftables.Element{ Set: types.NFTRemoteNodeIPsv4, Key: []string{nodeIP.String()}, }) - } else { + } + } + + // Process IPv6 addresses + for _, nodeIP := range ipsv6 { + addrs = append(addrs, nodeIP.String()) + klog.Infof("Adding remote node %q, IP: %s to PMTUD blocking rules", node.Name, nodeIP) + // Only add to nftables if this is remote node + if node.Name != nc.name { nftElems = append(nftElems, &knftables.Element{ Set: types.NFTRemoteNodeIPsv6, Key: []string{nodeIP.String()}, @@ -1578,18 +1587,18 @@ func removePMTUDNodeNFTRules(nodeIPs []net.IP) error { func (nc *DefaultNodeNetworkController) deleteNode(node *corev1.Node) { gw := nc.Gateway.(*gateway) gw.openflowManager.deleteFlowsByKey(getPMTUDKey(node.Name)) - ipsToRemove := make([]net.IP, 0) - for _, address := range node.Status.Addresses { - if address.Type != corev1.NodeInternalIP { - continue - } - nodeIP := net.ParseIP(address.Address) - if nodeIP == nil { - continue - } - ipsToRemove = append(ipsToRemove, nodeIP) + + // Use GetNodeAddresses to get node IPs + ipsv4, ipsv6, err := util.GetNodeAddresses(config.IPv4Mode, config.IPv6Mode, node) + if err != nil { + klog.Errorf("Failed to get node addresses for node %q: %v", node.Name, err) + return } + ipsToRemove := make([]net.IP, 0, len(ipsv4)+len(ipsv6)) + ipsToRemove = append(ipsToRemove, ipsv4...) + ipsToRemove = append(ipsToRemove, ipsv6...) + klog.Infof("Deleting NFT elements for node: %s", node.Name) if err := removePMTUDNodeNFTRules(ipsToRemove); err != nil { klog.Errorf("Failed to delete nftables rules for PMTUD blocking for node %q: %v", node.Name, err) @@ -1610,27 +1619,28 @@ func (nc *DefaultNodeNetworkController) syncNodes(objs []interface{}) error { if node.Name == nc.name { continue } - for _, address := range node.Status.Addresses { - if address.Type != corev1.NodeInternalIP { - continue - } - nodeIP := net.ParseIP(address.Address) - if nodeIP == nil { - continue - } - // Remove IPs from NFT sets - if utilnet.IsIPv4(nodeIP) { - keepNFTSetElemsV4 = append(keepNFTSetElemsV4, &knftables.Element{ - Set: types.NFTRemoteNodeIPsv4, - Key: []string{nodeIP.String()}, - }) - } else { - keepNFTSetElemsV6 = append(keepNFTSetElemsV6, &knftables.Element{ - Set: types.NFTRemoteNodeIPsv6, - Key: []string{nodeIP.String()}, - }) - } + // Use GetNodeAddresses to get node IPs + ipsv4, ipsv6, err := util.GetNodeAddresses(config.IPv4Mode, config.IPv6Mode, node) + if err != nil { + klog.Errorf("Failed to get node addresses for node %q: %v", node.Name, err) + continue + } + + // Process IPv4 addresses + for _, nodeIP := range ipsv4 { + keepNFTSetElemsV4 = append(keepNFTSetElemsV4, &knftables.Element{ + Set: types.NFTRemoteNodeIPsv4, + Key: []string{nodeIP.String()}, + }) + } + + // Process IPv6 addresses + for _, nodeIP := range ipsv6 { + keepNFTSetElemsV6 = append(keepNFTSetElemsV6, &knftables.Element{ + Set: types.NFTRemoteNodeIPsv6, + Key: []string{nodeIP.String()}, + }) } } if err := recreateNFTSet(types.NFTRemoteNodeIPsv4, keepNFTSetElemsV4); err != nil { diff --git a/go-controller/pkg/node/default_node_network_controller_test.go b/go-controller/pkg/node/default_node_network_controller_test.go index 24c3141357..366ee881d6 100644 --- a/go-controller/pkg/node/default_node_network_controller_test.go +++ b/go-controller/pkg/node/default_node_network_controller_test.go @@ -755,6 +755,9 @@ var _ = Describe("Node", func() { node := corev1.Node{ ObjectMeta: metav1.ObjectMeta{ Name: nodeName, + Annotations: map[string]string{ + util.OVNNodeHostCIDRs: fmt.Sprintf("[\"%s\"]", nodeIP+"/24"), + }, }, Status: corev1.NodeStatus{ Addresses: []corev1.NodeAddress{ @@ -769,6 +772,9 @@ var _ = Describe("Node", func() { otherNode := corev1.Node{ ObjectMeta: metav1.ObjectMeta{ Name: remoteNodeName, + Annotations: map[string]string{ + util.OVNNodeHostCIDRs: fmt.Sprintf("[\"%s\"]", otherNodeIP+"/24"), + }, }, Status: corev1.NodeStatus{ Addresses: []corev1.NodeAddress{ @@ -860,6 +866,9 @@ add element inet ovn-kubernetes remote-node-ips-v4 { 169.254.254.61 } node := corev1.Node{ ObjectMeta: metav1.ObjectMeta{ Name: nodeName, + Annotations: map[string]string{ + util.OVNNodeHostCIDRs: fmt.Sprintf("[\"%s\"]", nodeIP+"/24"), + }, }, Status: corev1.NodeStatus{ Addresses: []corev1.NodeAddress{ @@ -874,6 +883,9 @@ add element inet ovn-kubernetes remote-node-ips-v4 { 169.254.254.61 } otherNode := corev1.Node{ ObjectMeta: metav1.ObjectMeta{ Name: remoteNodeName, + Annotations: map[string]string{ + util.OVNNodeHostCIDRs: fmt.Sprintf("[\"%s\"]", otherSubnetNodeIP+"/24"), + }, }, Status: corev1.NodeStatus{ Addresses: []corev1.NodeAddress{ @@ -1007,6 +1019,9 @@ add element inet ovn-kubernetes remote-node-ips-v4 { 169.254.253.61 } node := corev1.Node{ ObjectMeta: metav1.ObjectMeta{ Name: nodeName, + Annotations: map[string]string{ + util.OVNNodeHostCIDRs: fmt.Sprintf("[\"%s\"]", nodeIP+"/64"), + }, }, Status: corev1.NodeStatus{ Addresses: []corev1.NodeAddress{ @@ -1021,6 +1036,9 @@ add element inet ovn-kubernetes remote-node-ips-v4 { 169.254.253.61 } otherNode := corev1.Node{ ObjectMeta: metav1.ObjectMeta{ Name: remoteNodeName, + Annotations: map[string]string{ + util.OVNNodeHostCIDRs: fmt.Sprintf("[\"%s\"]", otherNodeIP+"/64"), + }, }, Status: corev1.NodeStatus{ Addresses: []corev1.NodeAddress{ @@ -1111,6 +1129,9 @@ add element inet ovn-kubernetes remote-node-ips-v6 { 2001:db8:1::4 } node := corev1.Node{ ObjectMeta: metav1.ObjectMeta{ Name: nodeName, + Annotations: map[string]string{ + util.OVNNodeHostCIDRs: fmt.Sprintf("[\"%s\"]", nodeIP+"/64"), + }, }, Status: corev1.NodeStatus{ Addresses: []corev1.NodeAddress{ @@ -1125,6 +1146,9 @@ add element inet ovn-kubernetes remote-node-ips-v6 { 2001:db8:1::4 } otherNode := corev1.Node{ ObjectMeta: metav1.ObjectMeta{ Name: remoteNodeName, + Annotations: map[string]string{ + util.OVNNodeHostCIDRs: fmt.Sprintf("[\"%s\"]", otherSubnetNodeIP+"/64"), + }, }, Status: corev1.NodeStatus{ Addresses: []corev1.NodeAddress{ diff --git a/go-controller/pkg/node/obj_retry_node.go b/go-controller/pkg/node/obj_retry_node.go index 9c9657678e..646cca2ac3 100644 --- a/go-controller/pkg/node/obj_retry_node.go +++ b/go-controller/pkg/node/obj_retry_node.go @@ -238,34 +238,43 @@ func (h *nodeEventHandler) UpdateResource(oldObj, newObj interface{}, _ bool) er return nil } - // remote node that is changing - ipsToKeep := map[string]bool{} - for _, address := range newNode.Status.Addresses { - if address.Type != corev1.NodeInternalIP { - continue + if util.NodeHostCIDRsAnnotationChanged(oldNode, newNode) { + // remote node that is changing + // Use GetNodeAddresses to get new node IPs + newIPsv4, newIPsv6, err := util.GetNodeAddresses(config.IPv4Mode, config.IPv6Mode, newNode) + if err != nil { + return fmt.Errorf("failed to get addresses for new node %q: %w", newNode.Name, err) } - nodeIP := net.ParseIP(address.Address) - if nodeIP == nil { - continue + + ipsToKeep := map[string]bool{} + for _, nodeIP := range newIPsv4 { + ipsToKeep[nodeIP.String()] = true } - ipsToKeep[nodeIP.String()] = true - } - ipsToRemove := make([]net.IP, 0) - for _, address := range oldNode.Status.Addresses { - if address.Type != corev1.NodeInternalIP { - continue + for _, nodeIP := range newIPsv6 { + ipsToKeep[nodeIP.String()] = true } - nodeIP := net.ParseIP(address.Address) - if nodeIP == nil { - continue + + // Use GetNodeAddresses to get old node IPs + oldIPsv4, oldIPsv6, err := util.GetNodeAddresses(config.IPv4Mode, config.IPv6Mode, oldNode) + if err != nil { + return fmt.Errorf("failed to get addresses for old node %q: %w", oldNode.Name, err) } - if _, exists := ipsToKeep[nodeIP.String()]; !exists { - ipsToRemove = append(ipsToRemove, nodeIP) + + ipsToRemove := make([]net.IP, 0) + for _, nodeIP := range oldIPsv4 { + if _, exists := ipsToKeep[nodeIP.String()]; !exists { + ipsToRemove = append(ipsToRemove, nodeIP) + } + } + for _, nodeIP := range oldIPsv6 { + if _, exists := ipsToKeep[nodeIP.String()]; !exists { + ipsToRemove = append(ipsToRemove, nodeIP) + } } - } - if err := removePMTUDNodeNFTRules(ipsToRemove); err != nil { - return fmt.Errorf("error removing node %q stale NFT rules during update: %w", oldNode.Name, err) + if err := removePMTUDNodeNFTRules(ipsToRemove); err != nil { + return fmt.Errorf("error removing node %q stale NFT rules during update: %w", oldNode.Name, err) + } } return h.nc.addOrUpdateNode(newNode) From 0635caef5d9a60f132b99889dd8a1376663c4294 Mon Sep 17 00:00:00 2001 From: Surya Seetharaman Date: Mon, 21 Jul 2025 22:42:32 +0200 Subject: [PATCH 016/115] cleanupStalePodSNATs: Don't blow all SNATs for advertised Networks Signed-off-by: Surya Seetharaman --- go-controller/pkg/ovn/gateway.go | 11 +++++------ go-controller/pkg/ovn/master_test.go | 25 ++++++++++++++++++++++--- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/go-controller/pkg/ovn/gateway.go b/go-controller/pkg/ovn/gateway.go index 66bce44dfe..d652dbcd8a 100644 --- a/go-controller/pkg/ovn/gateway.go +++ b/go-controller/pkg/ovn/gateway.go @@ -143,8 +143,8 @@ func WithLoadBalancerGroups(routerLBGroup, clusterLBGroup, switchLBGroup string) } // cleanupStalePodSNATs removes pod SNATs against nodeIP for the given node if -// the SNAT.logicalIP isn't an active podIP, the pod network is being advertised -// on this node or disableSNATMultipleGWs=false. We don't have to worry about +// the SNAT.logicalIP isn't an active podIP, or disableSNATMultipleGWs=false. +// We don't have to worry about // missing SNATs that should be added because addLogicalPort takes care of this // for all pods when RequestRetryObjs is called for each node add. // Other non-pod SNATs like join subnet SNATs are ignored. @@ -154,11 +154,11 @@ func WithLoadBalancerGroups(routerLBGroup, clusterLBGroup, switchLBGroup string) // pod->nodeSNATs which won't get cleared up unless explicitly deleted. // NOTE2: egressIP SNATs are synced in EIP controller. func (gw *GatewayManager) cleanupStalePodSNATs(nodeName string, nodeIPs []*net.IPNet, gwLRPIPs []net.IP) error { - // collect all the pod IPs for which we should be doing the SNAT; if the pod - // network is advertised or DisableSNATMultipleGWs==false we consider all + // collect all the pod IPs for which we should be doing the SNAT; + // if DisableSNATMultipleGWs==false we consider all // the SNATs stale podIPsWithSNAT := sets.New[string]() - if !gw.isRoutingAdvertised(nodeName) && config.Gateway.DisableSNATMultipleGWs { + if config.Gateway.DisableSNATMultipleGWs { pods, err := gw.watchFactory.GetAllPods() if err != nil { return fmt.Errorf("unable to list existing pods on node: %s, %w", @@ -231,7 +231,6 @@ func (gw *GatewayManager) cleanupStalePodSNATs(nodeName string, nodeIPs []*net.I } natsToDelete = append(natsToDelete, routerNat) } - if len(natsToDelete) > 0 { err := libovsdbops.DeleteNATs(gw.nbClient, gatewayRouter, natsToDelete...) if err != nil { diff --git a/go-controller/pkg/ovn/master_test.go b/go-controller/pkg/ovn/master_test.go index 866b6309fa..197ecf5c24 100644 --- a/go-controller/pkg/ovn/master_test.go +++ b/go-controller/pkg/ovn/master_test.go @@ -1259,6 +1259,12 @@ var _ = ginkgo.Describe("Default network controller operations", func() { newNodeSNAT("stale-nodeNAT-UUID-3", "10.0.0.3", Node1GatewayRouterIP), newNodeSNAT("stale-nodeNAT-UUID-4", "10.0.0.3", "172.16.16.3"), } + extraNatsWithMatch := []*nbdb.NAT{ // used for pod network advertised test + newNodeSNATWithMatch("stale-nodeNAT-UUID-1", "10.1.0.3", Node1GatewayRouterIP, "ip4.dst == $a712973235162149816"), + newNodeSNATWithMatch("stale-nodeNAT-UUID-2", "10.2.0.3", Node1GatewayRouterIP, "ip4.dst == $a712973235162149816"), + newNodeSNATWithMatch("stale-nodeNAT-UUID-3", "10.0.0.3", Node1GatewayRouterIP, "ip4.dst == $a712973235162149816"), + newNodeSNATWithMatch("stale-nodeNAT-UUID-4", "10.0.0.3", "172.16.16.3", "ip4.dst == $a712973235162149816"), + } ginkgo.DescribeTable( "reconciles pod network SNATs from syncGateway", func(condition func(*DefaultNetworkController) error, expectedExtraNATs ...*nbdb.NAT) { @@ -1284,7 +1290,11 @@ var _ = ginkgo.Describe("Default network controller operations", func() { GR := &nbdb.LogicalRouter{ Name: types.GWRouterPrefix + node1.Name, } - err = libovsdbops.CreateOrUpdateNATs(nbClient, GR, extraNats...) + if !oc.isPodNetworkAdvertisedAtNode(node1.Name) { + err = libovsdbops.CreateOrUpdateNATs(nbClient, GR, extraNats...) + } else { + err = libovsdbops.CreateOrUpdateNATs(nbClient, GR, extraNatsWithMatch...) + } gomega.Expect(err).NotTo(gomega.HaveOccurred()) // ensure the stale SNAT's are cleaned up @@ -1366,7 +1376,10 @@ var _ = ginkgo.Describe("Default network controller operations", func() { mutableNetInfo.SetPodNetworkAdvertisedVRFs(map[string][]string{"node1": {"vrf"}}) return oc.Reconcile(mutableNetInfo) }, - newNodeSNAT("stale-nodeNAT-UUID-4", "10.0.0.3", "172.16.16.3"), // won't be deleted on this node but will be deleted on the node whose IP is 172.16.16.3 since this pod belongs to this node + // won't be deleted on this node since this pod belongs to node-1 and is advertised so we keep this SNAT + newNodeSNATWithMatch("stale-nodeNAT-UUID-3", "10.0.0.3", Node1GatewayRouterIP, "ip4.dst == $a712973235162149816"), + // won't be deleted on this node but will be deleted on the node whose IP is 172.16.16.3 since this pod belongs to node-1 + newNodeSNATWithMatch("stale-nodeNAT-UUID-4", "10.0.0.3", "172.16.16.3", "ip4.dst == $a712973235162149816"), ), ginkgo.Entry( "When pod network is advertised and DisableSNATMultipleGWs is false", @@ -1377,7 +1390,7 @@ var _ = ginkgo.Describe("Default network controller operations", func() { mutableNetInfo.SetPodNetworkAdvertisedVRFs(map[string][]string{"node1": {"vrf"}}) return oc.Reconcile(mutableNetInfo) }, - newNodeSNAT("stale-nodeNAT-UUID-4", "10.0.0.3", "172.16.16.3"), // won't be deleted on this node but will be deleted on the node whose IP is 172.16.16.3 since this pod belongs to this node + newNodeSNATWithMatch("stale-nodeNAT-UUID-4", "10.0.0.3", "172.16.16.3", "ip4.dst == $a712973235162149816"), // won't be deleted on this node but will be deleted on the node whose IP is 172.16.16.3 since this pod belongs to this node ), ) @@ -1982,6 +1995,12 @@ func newNodeSNAT(uuid, logicalIP, externalIP string) *nbdb.NAT { } } +func newNodeSNATWithMatch(uuid, logicalIP, externalIP, match string) *nbdb.NAT { + nat := newNodeSNAT(uuid, logicalIP, externalIP) + nat.Match = match + return nat +} + func TestController_syncNodes(t *testing.T) { gomega.RegisterFailHandler(ginkgo.Fail) From 5056d4da4e8177e32f9aa00121acc43d712d369a Mon Sep 17 00:00:00 2001 From: Surya Seetharaman Date: Wed, 23 Jul 2025 11:17:08 +0200 Subject: [PATCH 017/115] Fix CreateOrUpdateNATs to update non-default values When using the onModelUpdatesAllNonDefault() from NAT updates, it wasn't updating match value when we wanted to reset it. So when we went from advertised network to non-advertised network, we were not changing the SNAT match and hence traffic was still going out with podIP instead of nodeIP. This commit fixes that. Signed-off-by: Surya Seetharaman --- go-controller/pkg/libovsdb/ops/router.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/go-controller/pkg/libovsdb/ops/router.go b/go-controller/pkg/libovsdb/ops/router.go index 27e8e38d48..5f0ce594d4 100644 --- a/go-controller/pkg/libovsdb/ops/router.go +++ b/go-controller/pkg/libovsdb/ops/router.go @@ -932,6 +932,11 @@ func RemoveLoadBalancersFromLogicalRouterOps(nbClient libovsdbclient.Client, ops return ops, err } +func getNATMutableFields(nat *nbdb.NAT) []interface{} { + return []interface{}{&nat.Type, &nat.ExternalIP, &nat.LogicalIP, &nat.LogicalPort, &nat.ExternalMAC, + &nat.ExternalIDs, &nat.Match, &nat.Options, &nat.ExternalPortRange, &nat.GatewayPort, &nat.Priority} +} + func buildNAT( natType nbdb.NATType, externalIP string, @@ -1152,7 +1157,7 @@ func CreateOrUpdateNATsOps(nbClient libovsdbclient.Client, ops []ovsdb.Operation } opModel := operationModel{ Model: inputNat, - OnModelUpdates: onModelUpdatesAllNonDefault(), + OnModelUpdates: getNATMutableFields(inputNat), ErrNotFound: false, BulkOp: false, DoAfter: func() { router.Nat = append(router.Nat, inputNat.UUID) }, @@ -1280,7 +1285,7 @@ func UpdateNATOps(nbClient libovsdbclient.Client, ops []ovsdb.Operation, nats .. opModel := []operationModel{ { Model: nat, - OnModelUpdates: onModelUpdatesAllNonDefault(), + OnModelUpdates: getNATMutableFields(nat), ErrNotFound: true, BulkOp: false, }, From bcd06566dd363440e6e0719e9ddec35425bae5fa Mon Sep 17 00:00:00 2001 From: Surya Seetharaman Date: Mon, 28 Jul 2025 16:38:13 +0200 Subject: [PATCH 018/115] Bump OVN to 25.03 Signed-off-by: Surya Seetharaman --- dist/images/Dockerfile.fedora | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/images/Dockerfile.fedora b/dist/images/Dockerfile.fedora index 4ca51e888f..fc42191887 100644 --- a/dist/images/Dockerfile.fedora +++ b/dist/images/Dockerfile.fedora @@ -79,7 +79,7 @@ RUN git log -n 1 # Stage to download OVN RPMs from koji # ######################################## FROM quay.io/fedora/fedora:42 AS kojidownloader -ARG ovnver=ovn-24.09.2-71.fc42 +ARG ovnver=ovn-25.03.1-42.fc42 USER root From e8fc76449f4f2a3259c4576de41abe6f3cd2110f Mon Sep 17 00:00:00 2001 From: Surya Seetharaman Date: Mon, 28 Jul 2025 20:35:55 +0200 Subject: [PATCH 019/115] UDN,L2: UDN pod in networkA to nodePort on networkB works for IPV6! See https://github.com/ovn-kubernetes/ovn-kubernetes/issues/5419 for details But the traffic flow looks like this for Layer3(v4 and v6) and Layer2(v4): pod in UDN A -> sameNodeIP:NodePort i.e 172.18.0.2:30724 pod (102.102.2.4)-> ovn-switch->ovn-cluster-router (SNAT to masqueradeIP 169.254.0.14)-> LRP send to mpX -> in the host (IPTable DNAT from nodePort to clusterIP 10.96.96.233:8080) send to breth0 breth0 flows reroute packet to UDN B's patchport hits the GR of UDNB and DNATs from clusterIP to backend pod that lives on another node (103.103.1.5) at the same time SNAT to joinIP in OVN router i.e 100.65.0.4 reponse comes back from remote pod and then we see ARP requests trying to understand how to reach the masqueradeIP of the other network which makes total sense - so reply fails NetworkB doesn't know how to reach back to NetworkA's masqueradeIP which is the srcIP. root@ovn-control-plane:/# tcpdump -i any -nneev port 36363 or port 30724 or host 102.102.2.4 or host 169.254.0.14 or host 100.65.0.4 tcpdump: data link type LINUX_SLL2 tcpdump: listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes 08:55:14.083364 865a53b516350_3 P ifindex 19 0a:58:66:66:02:04 ethertype IPv4 (0x0800), length 80: (tos 0x0, ttl 64, id 53100, offset 0, flags [DF], proto TCP (6), length 60) 102.102.2.4.42720 > 172.18.0.2.30724: Flags [S], cksum 0x14ad (incorrect -> 0x5e6c), seq 432663101, win 65280, options [mss 1360,sackOK,TS val 1239378349 ecr 0,nop,wscale 7], length 0 08:55:14.084049 ovn-k8s-mp2 In ifindex 14 0a:58:66:66:02:01 ethertype IPv4 (0x0800), length 80: (tos 0x0, ttl 63, id 53100, offset 0, flags [DF], proto TCP (6), length 60) 169.254.0.14.42826 > 172.18.0.2.30724: Flags [S], cksum 0x1c60 (correct), seq 432663101, win 65280, options [mss 1360,sackOK,TS val 1239378349 ecr 0,nop,wscale 7], length 0 08:55:14.084069 breth0 Out ifindex 6 6a:ed:17:fb:28:bd ethertype IPv4 (0x0800), length 80: (tos 0x0, ttl 62, id 53100, offset 0, flags [DF], proto TCP (6), length 60) 169.254.0.14.42826 > 10.96.96.233.8080: Flags [S], cksum 0xb59f (correct), seq 432663101, win 65280, options [mss 1360,sackOK,TS val 1239378349 ecr 0,nop,wscale 7], length 0 08:55:14.084470 genev_sys_6081 Out ifindex 7 0a:58:64:58:00:04 ethertype IPv4 (0x0800), length 80: (tos 0x0, ttl 60, id 53100, offset 0, flags [DF], proto TCP (6), length 60) 100.65.0.4.42826 > 103.103.1.5.8080: Flags [S], cksum 0xfe43 (correct), seq 432663101, win 65280, options [mss 1360,sackOK,TS val 1239378349 ecr 0,nop,wscale 7], length 0 08:55:14.085494 genev_sys_6081 P ifindex 7 0a:58:64:58:00:02 ethertype IPv4 (0x0800), length 80: (tos 0x0, ttl 63, id 0, offset 0, flags [DF], proto TCP (6), length 60) 103.103.1.5.8080 > 100.65.0.4.42826: Flags [S.], cksum 0x1f4f (correct), seq 3390013464, ack 432663102, win 64704, options [mss 1360,sackOK,TS val 1866737591 ecr 1239378349,nop,wscale 7], length 0 08:55:14.086130 eth0 Out ifindex 2 6a:ed:17:fb:28:bd ethertype ARP (0x0806), length 48: Ethernet (len 6), IPv4 (len 4), Request who-has 169.254.0.14 tell 169.254.0.15, length 28 08:55:14.086172 breth0 B ifindex 6 6a:ed:17:fb:28:bd ethertype ARP (0x0806), length 48: Ethernet (len 6), IPv4 (len 4), Request who-has 169.254.0.14 tell 169.254.0.15, length 28 08:55:15.100558 genev_sys_6081 P ifindex 7 0a:58:64:58:00:02 ethertype IPv4 (0x0800), length 80: (tos 0x0, ttl 63, id 0, offset 0, flags [DF], proto TCP (6), length 60) 103.103.1.5.8080 > 100.65.0.4.42826: Flags [S.], cksum 0xccdf (incorrect -> 0x1b57), seq 3390013464, ack 432663102, win 64704, options [mss 1360,sackOK,TS val 1866738607 ecr 1239378349,nop,wscale 7], length 0 08:55:15.101090 eth0 Out ifindex 2 6a:ed:17:fb:28:bd ethertype ARP (0x0806), length 48: Ethernet (len 6), IPv4 (len 4), Request who-has 169.254.0.14 tell 169.254.0.15, length 28 08:55:15.101124 breth0 B ifindex 6 6a:ed:17:fb:28:bd ethertype ARP (0x0806), length 48: Ethernet (len 6), IPv4 (len 4), Request who-has 169.254.0.14 tell 169.254.0.15, length 28 ^ its the same for Layer3 v6 as well and same for Layer2 v4 ^^ but Layer2 v6 is weird thanks to: // cookie=0xdeff105, duration=173.245s, table=1, n_packets=0, n_bytes=0, idle_age=173, priority=14,icmp6,icmp_type=134 actions=FLOOD // cookie=0xdeff105, duration=173.245s, table=1, n_packets=8, n_bytes=640, idle_age=4, priority=14,icmp6,icmp_type=136 actions=FLOOD these two flows on breth0 - these seem to be flooding the NDP requests between the GR's of all networks somehow and v6 works. So test is acknowledging this inconsistency and calling this out. Signed-off-by: Surya Seetharaman --- test/e2e/route_advertisements.go | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/test/e2e/route_advertisements.go b/test/e2e/route_advertisements.go index 026dfc5901..36c0c5c950 100644 --- a/test/e2e/route_advertisements.go +++ b/test/e2e/route_advertisements.go @@ -1035,15 +1035,40 @@ var _ = ginkgo.DescribeTableSubtree("BGP: isolation between advertised networks" }), ginkgo.Entry("UDN pod to the same node nodeport service in different UDN network should not work", // FIXME: This test should work: https://github.com/ovn-kubernetes/ovn-kubernetes/issues/5419 + // This traffic flow is expected to work eventually but doesn't work today on Layer3 (v4 and v6) and Layer2 (v4 only) networks. + // Reason it doesn't work today is because UDN networks don't have MAC bindings for masqueradeIPs of other networks. + // Traffic flow: UDN pod in network A -> samenode nodeIP:nodePort service of networkB + // UDN pod in networkA -> ovn-switch -> ovn-cluster-router (SNAT to masqueradeIP of networkA) -> mpX interface -> + // enters the host and hits IPTables rules to DNAT to clusterIP:Port of service of networkB. + // Then it hits the pkt_mark flows on breth0 and get's sent into networkB's patchport where it hits the GR. + // On the GR we DNAT to backend pod and SNAT to joinIP. + // Reply: Pod replies and now OVN in networkB tries to ARP for the masqueradeIP of networkA which is the source and simply + // fails as it doesn't know how to reach this masqueradeIP. + // There is also inconsistency in behaviour within Layer2 networks for how IPv4 works and how IPv6 works where the traffic + // works on ipv6 because of the flows described below. func(ipFamilyIndex int) (clientName string, clientNamespace string, dst string, expectedOutput string, expectErr bool) { clientPod := podsNetA[0] node, err := f.ClientSet.CoreV1().Nodes().Get(context.TODO(), nodes.Items[0].Name, metav1.GetOptions{}) framework.ExpectNoError(err) nodeIP := node.Status.Addresses[ipFamilyIndex].Address nodePort := svcNetB.Spec.Ports[0].NodePort + out := curlConnectionTimeoutCode + errBool := true + if ipFamilyIndex == ipFamilyV6 && cudnATemplate.Spec.Network.Topology == udnv1.NetworkTopologyLayer2 { + // For Layer2 networks, we have these flows we add on breth0: + // cookie=0xdeff105, duration=173.245s, table=1, n_packets=0, n_bytes=0, idle_age=173, priority=14,icmp6,icmp_type=134 actions=FLOOD + // cookie=0xdeff105, duration=173.245s, table=1, n_packets=8, n_bytes=640, idle_age=4, priority=14,icmp6,icmp_type=136 actions=FLOOD + // which floods the Router Advertisement (RA, type 134) and Neighbor Advertisement (NA, type 136) + // Given on Layer2 the GR has the SNATs for both masqueradeIPs this works perfectly well and + // the networks are able to NDP for the masqueradeIPs for the other networks. + // This doesn't work on Layer3 networks since masqueradeIP SNATs are present on the ovn-cluster-router in that case. + // See the tcpdump on the issue: https://github.com/ovn-kubernetes/ovn-kubernetes/issues/5410 for more details. + out = "" + errBool = false + } // sourceIP will be joinSubnetIP for nodeports, so only using hostname endpoint - return clientPod.Name, clientPod.Namespace, net.JoinHostPort(nodeIP, fmt.Sprint(nodePort)) + "/hostname", curlConnectionTimeoutCode, true + return clientPod.Name, clientPod.Namespace, net.JoinHostPort(nodeIP, fmt.Sprint(nodePort)) + "/hostname", out, errBool }), ginkgo.Entry("UDN pod to a different node nodeport service in different UDN network should work", func(ipFamilyIndex int) (clientName string, clientNamespace string, dst string, expectedOutput string, expectErr bool) { From 9b21fc066d954bacd511a899c3bca464fc97e21a Mon Sep 17 00:00:00 2001 From: Surya Seetharaman Date: Tue, 29 Jul 2025 11:09:19 +0200 Subject: [PATCH 020/115] Change OVN-Kubernetes community meeting time Makes this EMEA/US friendly. Signed-off-by: Surya Seetharaman --- MEETINGS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MEETINGS.md b/MEETINGS.md index 701459788f..8964025628 100644 --- a/MEETINGS.md +++ b/MEETINGS.md @@ -6,7 +6,7 @@ All are welcome to join our meetings! If you want to discuss something with the ## Meeting time -We meet alternate Monday's at 6:00 PM CET/CEST. +We meet alternate Monday's at 5:00 PM CET/CEST. In order to figure out when our next meeting is, please check our agenda for previous meeting history. The meetings last up to 1 hour. From cc6fe11a70b5c215883f4abf9d099523cc457956 Mon Sep 17 00:00:00 2001 From: Miguel Duarte Barroso Date: Thu, 19 Jun 2025 10:48:16 +0100 Subject: [PATCH 021/115] udn, pre assigned port net ids: provision the default net NAD CR The "pre assigned port net ids" feature requires a NAD for the `default` network to be provisioned. This commit pre-provisions that NAD whenever the feature - EnableCustomNetworkConfig - is enabled, upon starting the cluster manager. Signed-off-by: Miguel Duarte Barroso --- .../pkg/clustermanager/clustermanager_test.go | 107 +++++++++++++++++- .../routeadvertisements/controller.go | 30 +---- .../routeadvertisements/controller_test.go | 2 +- .../userdefinednetwork/controller.go | 6 + go-controller/pkg/util/multi_network.go | 6 + go-controller/pkg/util/nad.go | 46 ++++++++ 6 files changed, 161 insertions(+), 36 deletions(-) create mode 100644 go-controller/pkg/util/nad.go diff --git a/go-controller/pkg/clustermanager/clustermanager_test.go b/go-controller/pkg/clustermanager/clustermanager_test.go index f97de8fc3f..66535f4c8a 100644 --- a/go-controller/pkg/clustermanager/clustermanager_test.go +++ b/go-controller/pkg/clustermanager/clustermanager_test.go @@ -34,10 +34,9 @@ const ( var _ = ginkgo.Describe("Cluster Manager", func() { var ( - app *cli.App - f *factory.WatchFactory - stopChan chan struct{} - wg *sync.WaitGroup + app *cli.App + f *factory.WatchFactory + wg *sync.WaitGroup ) const ( @@ -54,12 +53,10 @@ var _ = ginkgo.Describe("Cluster Manager", func() { app = cli.NewApp() app.Name = "test" app.Flags = config.Flags - stopChan = make(chan struct{}) wg = &sync.WaitGroup{} }) ginkgo.AfterEach(func() { - close(stopChan) if f != nil { f.Shutdown() } @@ -1436,4 +1433,102 @@ var _ = ginkgo.Describe("Cluster Manager", func() { }) }) + ginkgo.Context("starting the cluster manager", func() { + const networkName = "default" + + var fakeClient *util.OVNClusterManagerClientset + + ginkgo.BeforeEach(func() { + fakeClient = util.GetOVNClientset().GetClusterManagerClientset() + }) + + ginkgo.When("the required features are not enabled", func() { + ginkgo.It("does *not* automatically provision a NAD for the default network", func() { + app.Action = func(ctx *cli.Context) error { + _, err := config.InitConfig(ctx, nil, nil) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + + f, err = factory.NewClusterManagerWatchFactory(fakeClient) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + + clusterMngr, err := clusterManager(fakeClient, f) + gomega.Expect(clusterMngr).NotTo(gomega.BeNil()) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + gomega.Expect(clusterMngr.Start(ctx.Context)).To(gomega.Succeed()) + + _, err = fakeClient.NetworkAttchDefClient. + K8sCniCncfIoV1(). + NetworkAttachmentDefinitions(config.Kubernetes.OVNConfigNamespace). + Get( + context.Background(), + networkName, + metav1.GetOptions{}, + ) + gomega.Expect(err).To( + gomega.MatchError("network-attachment-definitions.k8s.cni.cncf.io \"default\" not found"), + ) + + return nil + } + gomega.Expect(app.Run([]string{app.Name})).To(gomega.Succeed()) + }) + }) + + ginkgo.When("the multi-network, network-segmentation, and preconfigured-udn-addresses features are enabled", func() { + ginkgo.BeforeEach(func() { + config.OVNKubernetesFeature.EnableMultiNetwork = true + config.OVNKubernetesFeature.EnableNetworkSegmentation = true + config.OVNKubernetesFeature.EnablePreconfiguredUDNAddresses = true + }) + + ginkgo.It("automatically provisions a NAD for the default network", func() { + app.Action = func(ctx *cli.Context) error { + _, err := config.InitConfig(ctx, nil, nil) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + + f, err = factory.NewClusterManagerWatchFactory(fakeClient) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + + clusterMngr, err := clusterManager(fakeClient, f) + gomega.Expect(clusterMngr).NotTo(gomega.BeNil()) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + + c, cancel := context.WithCancel(ctx.Context) + defer cancel() + gomega.Expect(clusterMngr.Start(c)).To(gomega.Succeed()) + defer clusterMngr.Stop() + + nad, err := fakeClient.NetworkAttchDefClient. + K8sCniCncfIoV1(). + NetworkAttachmentDefinitions(config.Kubernetes.OVNConfigNamespace). + Get( + context.Background(), + networkName, + metav1.GetOptions{}, + ) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + + const expectedNADContents = `{"cniVersion": "0.4.0", "name": "ovn-kubernetes", "type": "ovn-k8s-cni-overlay"}` + gomega.Expect(nad.Spec.Config).To(gomega.Equal(expectedNADContents)) + + return nil + } + gomega.Expect(app.Run([]string{app.Name})).To(gomega.Succeed()) + }) + }) + }) + }) + +func clusterManager(client *util.OVNClusterManagerClientset, f *factory.WatchFactory) (*ClusterManager, error) { + if err := f.Start(); err != nil { + return nil, fmt.Errorf("failed to start the CM watch factory: %w", err) + } + + clusterMngr, err := NewClusterManager(client, f, "identity", nil) + if err != nil { + return nil, fmt.Errorf("failed to start the CM watch factory: %w", err) + } + + return clusterMngr, nil +} diff --git a/go-controller/pkg/clustermanager/routeadvertisements/controller.go b/go-controller/pkg/clustermanager/routeadvertisements/controller.go index 18fb3dbaae..903f5622f2 100644 --- a/go-controller/pkg/clustermanager/routeadvertisements/controller.go +++ b/go-controller/pkg/clustermanager/routeadvertisements/controller.go @@ -1016,7 +1016,7 @@ func (c *Controller) getSelectedNADs(networkSelectors apitypes.NetworkSelectors) case apitypes.DefaultNetwork: // if we are selecting the default networkdefault network label, // make sure a NAD exists for it - nad, err := c.getOrCreateDefaultNetworkNAD() + nad, err := util.EnsureDefaultNetworkNAD(c.nadLister, c.nadClient) if err != nil { return nil, fmt.Errorf("failed to get/create default network NAD: %w", err) } @@ -1047,34 +1047,6 @@ func (c *Controller) getSelectedNADs(networkSelectors apitypes.NetworkSelectors) return selected, nil } -// getOrCreateDefaultNetworkNAD ensure that a well-known NAD exists for the -// default network in ovn-k namespace. -func (c *Controller) getOrCreateDefaultNetworkNAD() (*nadtypes.NetworkAttachmentDefinition, error) { - nad, err := c.nadLister.NetworkAttachmentDefinitions(config.Kubernetes.OVNConfigNamespace).Get(types.DefaultNetworkName) - if err != nil && !apierrors.IsNotFound(err) { - return nil, err - } - if nad != nil { - return nad, nil - } - return c.nadClient.K8sCniCncfIoV1().NetworkAttachmentDefinitions(config.Kubernetes.OVNConfigNamespace).Create( - context.Background(), - &nadtypes.NetworkAttachmentDefinition{ - ObjectMeta: metav1.ObjectMeta{ - Name: types.DefaultNetworkName, - Namespace: config.Kubernetes.OVNConfigNamespace, - }, - Spec: nadtypes.NetworkAttachmentDefinitionSpec{ - Config: fmt.Sprintf("{\"cniVersion\": \"0.4.0\", \"name\": \"ovn-kubernetes\", \"type\": \"%s\"}", config.CNI.Plugin), - }, - }, - // note we don't set ourselves as field manager for this create as we - // want to process the resulting event that would otherwise be filtered - // out in nadNeedsUpdate - metav1.CreateOptions{}, - ) -} - // getEgressIPsByNodesByNetworks iterates all existing egress IPs that apply to // any of the provided networks and returns a "node -> network -> eips" // map. diff --git a/go-controller/pkg/clustermanager/routeadvertisements/controller_test.go b/go-controller/pkg/clustermanager/routeadvertisements/controller_test.go index 305418425c..86c711987e 100644 --- a/go-controller/pkg/clustermanager/routeadvertisements/controller_test.go +++ b/go-controller/pkg/clustermanager/routeadvertisements/controller_test.go @@ -1051,7 +1051,7 @@ func TestController_reconcile(t *testing.T) { g.Expect(err).ToNot(gomega.HaveOccurred()) // prime the default network NAD if defaultNAD == nil { - defaultNAD, err = c.getOrCreateDefaultNetworkNAD() + defaultNAD, err = util.EnsureDefaultNetworkNAD(c.nadLister, c.nadClient) g.Expect(err).ToNot(gomega.HaveOccurred()) // update it with the annotation that network manager would set defaultNAD.Annotations = map[string]string{types.OvnNetworkNameAnnotation: types.DefaultNetworkName} diff --git a/go-controller/pkg/clustermanager/userdefinednetwork/controller.go b/go-controller/pkg/clustermanager/userdefinednetwork/controller.go index 67292bd2ed..14963b9ed9 100644 --- a/go-controller/pkg/clustermanager/userdefinednetwork/controller.go +++ b/go-controller/pkg/clustermanager/userdefinednetwork/controller.go @@ -150,6 +150,12 @@ func (c *Controller) Run() error { return fmt.Errorf("unable to start user-defined network controller: %v", err) } + if util.IsPreconfiguredUDNAddressesEnabled() { + if _, err := util.EnsureDefaultNetworkNAD(c.nadLister, c.nadClient); err != nil { + return fmt.Errorf("failed to ensure default network nad exists: %w", err) + } + } + return nil } diff --git a/go-controller/pkg/util/multi_network.go b/go-controller/pkg/util/multi_network.go index fd91edd3be..d4f8b2a948 100644 --- a/go-controller/pkg/util/multi_network.go +++ b/go-controller/pkg/util/multi_network.go @@ -1378,6 +1378,12 @@ func IsRouteAdvertisementsEnabled() bool { return config.OVNKubernetesFeature.EnableMultiNetwork && config.OVNKubernetesFeature.EnableRouteAdvertisements } +// IsPreconfiguredUDNAddressesEnabled indicates if user defined IPs / MAC +// addresses can be set in primary UDNs +func IsPreconfiguredUDNAddressesEnabled() bool { + return IsNetworkSegmentationSupportEnabled() && config.OVNKubernetesFeature.EnablePreconfiguredUDNAddresses +} + func DoesNetworkRequireIPAM(netInfo NetInfo) bool { return !((netInfo.TopologyType() == types.Layer2Topology || netInfo.TopologyType() == types.LocalnetTopology) && len(netInfo.Subnets()) == 0) } diff --git a/go-controller/pkg/util/nad.go b/go-controller/pkg/util/nad.go new file mode 100644 index 0000000000..3a220e2b82 --- /dev/null +++ b/go-controller/pkg/util/nad.go @@ -0,0 +1,46 @@ +package util + +import ( + "context" + "fmt" + + nadtypes "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1" + nadclientset "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/client/clientset/versioned" + nadlisters "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/client/listers/k8s.cni.cncf.io/v1" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/config" + "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/types" +) + +// EnsureDefaultNetworkNAD ensures that a well-known NAD exists for the +// default network in ovn-k namespace. This will allow the users to customize +// the primary UDN attachments with static IPs, and/or MAC address requests, by +// using the multus-cni `default network` feature. +func EnsureDefaultNetworkNAD(nadLister nadlisters.NetworkAttachmentDefinitionLister, nadClient nadclientset.Interface) (*nadtypes.NetworkAttachmentDefinition, error) { + nad, err := nadLister.NetworkAttachmentDefinitions(config.Kubernetes.OVNConfigNamespace).Get(types.DefaultNetworkName) + if err != nil && !apierrors.IsNotFound(err) { + return nil, err + } + if nad != nil { + return nad, nil + } + return nadClient.K8sCniCncfIoV1().NetworkAttachmentDefinitions(config.Kubernetes.OVNConfigNamespace).Create( + context.Background(), + &nadtypes.NetworkAttachmentDefinition{ + ObjectMeta: metav1.ObjectMeta{ + Name: types.DefaultNetworkName, + Namespace: config.Kubernetes.OVNConfigNamespace, + }, + Spec: nadtypes.NetworkAttachmentDefinitionSpec{ + Config: fmt.Sprintf("{\"cniVersion\": \"0.4.0\", \"name\": \"ovn-kubernetes\", \"type\": \"%s\"}", config.CNI.Plugin), + }, + }, + // note we don't set ourselves as field manager for this create as we + // want to process the resulting event that would otherwise be filtered + // out in nadNeedsUpdate + metav1.CreateOptions{}, + ) +} From b85c0f5f291fe964b68048878e79f5863358e2a8 Mon Sep 17 00:00:00 2001 From: Dave Tucker Date: Wed, 30 Jul 2025 11:03:20 +0100 Subject: [PATCH 022/115] chore: Update libovsdb bindings to ovn 25.03 Signed-off-by: Dave Tucker --- go-controller/Makefile | 3 +- go-controller/pkg/nbdb/load_balancer.go | 20 +- .../pkg/nbdb/logical_router_policy.go | 51 +++++ .../pkg/nbdb/logical_router_static_route.go | 67 +++++-- go-controller/pkg/nbdb/logical_switch_port.go | 25 +++ go-controller/pkg/nbdb/model.go | 62 +++++- go-controller/pkg/nbdb/ssl.go | 6 + go-controller/pkg/sbdb/acl_id.go | 54 ++++++ go-controller/pkg/sbdb/advertised_route.go | 124 ++++++++++++ go-controller/pkg/sbdb/ecmp_nexthop.go | 105 ++++++++++ go-controller/pkg/sbdb/learned_route.go | 105 ++++++++++ go-controller/pkg/sbdb/model.go | 180 +++++++++++++++++- go-controller/pkg/sbdb/ssl.go | 6 + 13 files changed, 780 insertions(+), 28 deletions(-) create mode 100644 go-controller/pkg/sbdb/acl_id.go create mode 100644 go-controller/pkg/sbdb/advertised_route.go create mode 100644 go-controller/pkg/sbdb/ecmp_nexthop.go create mode 100644 go-controller/pkg/sbdb/learned_route.go diff --git a/go-controller/Makefile b/go-controller/Makefile index 4c86486ce2..f27bb979e5 100644 --- a/go-controller/Makefile +++ b/go-controller/Makefile @@ -22,8 +22,7 @@ else CONTAINER_RUNTIME=docker endif CONTAINER_RUNNABLE ?= $(shell $(CONTAINER_RUNTIME) -v > /dev/null 2>&1; echo $$?) -# FIXME(tssurya): In one week when OVN 24.09 is released change the schema version -OVN_SCHEMA_VERSION ?= 8efac26f6637fc +OVN_SCHEMA_VERSION ?= v25.03.1 OVS_VERSION ?= v2.17.0 ifeq ($(NOROOT),TRUE) C_ARGS = -e NOROOT=TRUE diff --git a/go-controller/pkg/nbdb/load_balancer.go b/go-controller/pkg/nbdb/load_balancer.go index 8bddd25f4a..553bc48dda 100644 --- a/go-controller/pkg/nbdb/load_balancer.go +++ b/go-controller/pkg/nbdb/load_balancer.go @@ -13,15 +13,17 @@ type ( ) var ( - LoadBalancerProtocolTCP LoadBalancerProtocol = "tcp" - LoadBalancerProtocolUDP LoadBalancerProtocol = "udp" - LoadBalancerProtocolSCTP LoadBalancerProtocol = "sctp" - LoadBalancerSelectionFieldsEthSrc LoadBalancerSelectionFields = "eth_src" - LoadBalancerSelectionFieldsEthDst LoadBalancerSelectionFields = "eth_dst" - LoadBalancerSelectionFieldsIPSrc LoadBalancerSelectionFields = "ip_src" - LoadBalancerSelectionFieldsIPDst LoadBalancerSelectionFields = "ip_dst" - LoadBalancerSelectionFieldsTpSrc LoadBalancerSelectionFields = "tp_src" - LoadBalancerSelectionFieldsTpDst LoadBalancerSelectionFields = "tp_dst" + LoadBalancerProtocolTCP LoadBalancerProtocol = "tcp" + LoadBalancerProtocolUDP LoadBalancerProtocol = "udp" + LoadBalancerProtocolSCTP LoadBalancerProtocol = "sctp" + LoadBalancerSelectionFieldsEthSrc LoadBalancerSelectionFields = "eth_src" + LoadBalancerSelectionFieldsEthDst LoadBalancerSelectionFields = "eth_dst" + LoadBalancerSelectionFieldsIPSrc LoadBalancerSelectionFields = "ip_src" + LoadBalancerSelectionFieldsIPDst LoadBalancerSelectionFields = "ip_dst" + LoadBalancerSelectionFieldsIpv6Src LoadBalancerSelectionFields = "ipv6_src" + LoadBalancerSelectionFieldsIpv6Dst LoadBalancerSelectionFields = "ipv6_dst" + LoadBalancerSelectionFieldsTpSrc LoadBalancerSelectionFields = "tp_src" + LoadBalancerSelectionFieldsTpDst LoadBalancerSelectionFields = "tp_dst" ) // LoadBalancer defines an object in Load_Balancer table diff --git a/go-controller/pkg/nbdb/logical_router_policy.go b/go-controller/pkg/nbdb/logical_router_policy.go index 51b29ea706..377ef213d0 100644 --- a/go-controller/pkg/nbdb/logical_router_policy.go +++ b/go-controller/pkg/nbdb/logical_router_policy.go @@ -15,6 +15,7 @@ var ( LogicalRouterPolicyActionAllow LogicalRouterPolicyAction = "allow" LogicalRouterPolicyActionDrop LogicalRouterPolicyAction = "drop" LogicalRouterPolicyActionReroute LogicalRouterPolicyAction = "reroute" + LogicalRouterPolicyActionJump LogicalRouterPolicyAction = "jump" ) // LogicalRouterPolicy defines an object in Logical_Router_Policy table @@ -22,7 +23,9 @@ type LogicalRouterPolicy struct { UUID string `ovsdb:"_uuid"` Action LogicalRouterPolicyAction `ovsdb:"action"` BFDSessions []string `ovsdb:"bfd_sessions"` + Chain *string `ovsdb:"chain"` ExternalIDs map[string]string `ovsdb:"external_ids"` + JumpChain *string `ovsdb:"jump_chain"` Match string `ovsdb:"match"` Nexthop *string `ovsdb:"nexthop"` Nexthops []string `ovsdb:"nexthops"` @@ -66,6 +69,28 @@ func equalLogicalRouterPolicyBFDSessions(a, b []string) bool { return true } +func (a *LogicalRouterPolicy) GetChain() *string { + return a.Chain +} + +func copyLogicalRouterPolicyChain(a *string) *string { + if a == nil { + return nil + } + b := *a + return &b +} + +func equalLogicalRouterPolicyChain(a, b *string) bool { + if (a == nil) != (b == nil) { + return false + } + if a == b { + return true + } + return *a == *b +} + func (a *LogicalRouterPolicy) GetExternalIDs() map[string]string { return a.ExternalIDs } @@ -96,6 +121,28 @@ func equalLogicalRouterPolicyExternalIDs(a, b map[string]string) bool { return true } +func (a *LogicalRouterPolicy) GetJumpChain() *string { + return a.JumpChain +} + +func copyLogicalRouterPolicyJumpChain(a *string) *string { + if a == nil { + return nil + } + b := *a + return &b +} + +func equalLogicalRouterPolicyJumpChain(a, b *string) bool { + if (a == nil) != (b == nil) { + return false + } + if a == b { + return true + } + return *a == *b +} + func (a *LogicalRouterPolicy) GetMatch() string { return a.Match } @@ -187,7 +234,9 @@ func (a *LogicalRouterPolicy) GetPriority() int { func (a *LogicalRouterPolicy) DeepCopyInto(b *LogicalRouterPolicy) { *b = *a b.BFDSessions = copyLogicalRouterPolicyBFDSessions(a.BFDSessions) + b.Chain = copyLogicalRouterPolicyChain(a.Chain) b.ExternalIDs = copyLogicalRouterPolicyExternalIDs(a.ExternalIDs) + b.JumpChain = copyLogicalRouterPolicyJumpChain(a.JumpChain) b.Nexthop = copyLogicalRouterPolicyNexthop(a.Nexthop) b.Nexthops = copyLogicalRouterPolicyNexthops(a.Nexthops) b.Options = copyLogicalRouterPolicyOptions(a.Options) @@ -212,7 +261,9 @@ func (a *LogicalRouterPolicy) Equals(b *LogicalRouterPolicy) bool { return a.UUID == b.UUID && a.Action == b.Action && equalLogicalRouterPolicyBFDSessions(a.BFDSessions, b.BFDSessions) && + equalLogicalRouterPolicyChain(a.Chain, b.Chain) && equalLogicalRouterPolicyExternalIDs(a.ExternalIDs, b.ExternalIDs) && + equalLogicalRouterPolicyJumpChain(a.JumpChain, b.JumpChain) && a.Match == b.Match && equalLogicalRouterPolicyNexthop(a.Nexthop, b.Nexthop) && equalLogicalRouterPolicyNexthops(a.Nexthops, b.Nexthops) && diff --git a/go-controller/pkg/nbdb/logical_router_static_route.go b/go-controller/pkg/nbdb/logical_router_static_route.go index 205741626c..ceccb8ac78 100644 --- a/go-controller/pkg/nbdb/logical_router_static_route.go +++ b/go-controller/pkg/nbdb/logical_router_static_route.go @@ -8,25 +8,36 @@ import "github.com/ovn-kubernetes/libovsdb/model" const LogicalRouterStaticRouteTable = "Logical_Router_Static_Route" type ( - LogicalRouterStaticRoutePolicy = string + LogicalRouterStaticRoutePolicy = string + LogicalRouterStaticRouteSelectionFields = string ) var ( - LogicalRouterStaticRoutePolicySrcIP LogicalRouterStaticRoutePolicy = "src-ip" - LogicalRouterStaticRoutePolicyDstIP LogicalRouterStaticRoutePolicy = "dst-ip" + LogicalRouterStaticRoutePolicySrcIP LogicalRouterStaticRoutePolicy = "src-ip" + LogicalRouterStaticRoutePolicyDstIP LogicalRouterStaticRoutePolicy = "dst-ip" + LogicalRouterStaticRouteSelectionFieldsEthSrc LogicalRouterStaticRouteSelectionFields = "eth_src" + LogicalRouterStaticRouteSelectionFieldsEthDst LogicalRouterStaticRouteSelectionFields = "eth_dst" + LogicalRouterStaticRouteSelectionFieldsIPProto LogicalRouterStaticRouteSelectionFields = "ip_proto" + LogicalRouterStaticRouteSelectionFieldsIPSrc LogicalRouterStaticRouteSelectionFields = "ip_src" + LogicalRouterStaticRouteSelectionFieldsIPDst LogicalRouterStaticRouteSelectionFields = "ip_dst" + LogicalRouterStaticRouteSelectionFieldsIpv6Src LogicalRouterStaticRouteSelectionFields = "ipv6_src" + LogicalRouterStaticRouteSelectionFieldsIpv6Dst LogicalRouterStaticRouteSelectionFields = "ipv6_dst" + LogicalRouterStaticRouteSelectionFieldsTpSrc LogicalRouterStaticRouteSelectionFields = "tp_src" + LogicalRouterStaticRouteSelectionFieldsTpDst LogicalRouterStaticRouteSelectionFields = "tp_dst" ) // LogicalRouterStaticRoute defines an object in Logical_Router_Static_Route table type LogicalRouterStaticRoute struct { - UUID string `ovsdb:"_uuid"` - BFD *string `ovsdb:"bfd"` - ExternalIDs map[string]string `ovsdb:"external_ids"` - IPPrefix string `ovsdb:"ip_prefix"` - Nexthop string `ovsdb:"nexthop"` - Options map[string]string `ovsdb:"options"` - OutputPort *string `ovsdb:"output_port"` - Policy *LogicalRouterStaticRoutePolicy `ovsdb:"policy"` - RouteTable string `ovsdb:"route_table"` + UUID string `ovsdb:"_uuid"` + BFD *string `ovsdb:"bfd"` + ExternalIDs map[string]string `ovsdb:"external_ids"` + IPPrefix string `ovsdb:"ip_prefix"` + Nexthop string `ovsdb:"nexthop"` + Options map[string]string `ovsdb:"options"` + OutputPort *string `ovsdb:"output_port"` + Policy *LogicalRouterStaticRoutePolicy `ovsdb:"policy"` + RouteTable string `ovsdb:"route_table"` + SelectionFields []LogicalRouterStaticRouteSelectionFields `ovsdb:"selection_fields"` } func (a *LogicalRouterStaticRoute) GetUUID() string { @@ -171,6 +182,34 @@ func (a *LogicalRouterStaticRoute) GetRouteTable() string { return a.RouteTable } +func (a *LogicalRouterStaticRoute) GetSelectionFields() []LogicalRouterStaticRouteSelectionFields { + return a.SelectionFields +} + +func copyLogicalRouterStaticRouteSelectionFields(a []LogicalRouterStaticRouteSelectionFields) []LogicalRouterStaticRouteSelectionFields { + if a == nil { + return nil + } + b := make([]LogicalRouterStaticRouteSelectionFields, len(a)) + copy(b, a) + return b +} + +func equalLogicalRouterStaticRouteSelectionFields(a, b []LogicalRouterStaticRouteSelectionFields) bool { + if (a == nil) != (b == nil) { + return false + } + if len(a) != len(b) { + return false + } + for i, v := range a { + if b[i] != v { + return false + } + } + return true +} + func (a *LogicalRouterStaticRoute) DeepCopyInto(b *LogicalRouterStaticRoute) { *b = *a b.BFD = copyLogicalRouterStaticRouteBFD(a.BFD) @@ -178,6 +217,7 @@ func (a *LogicalRouterStaticRoute) DeepCopyInto(b *LogicalRouterStaticRoute) { b.Options = copyLogicalRouterStaticRouteOptions(a.Options) b.OutputPort = copyLogicalRouterStaticRouteOutputPort(a.OutputPort) b.Policy = copyLogicalRouterStaticRoutePolicy(a.Policy) + b.SelectionFields = copyLogicalRouterStaticRouteSelectionFields(a.SelectionFields) } func (a *LogicalRouterStaticRoute) DeepCopy() *LogicalRouterStaticRoute { @@ -204,7 +244,8 @@ func (a *LogicalRouterStaticRoute) Equals(b *LogicalRouterStaticRoute) bool { equalLogicalRouterStaticRouteOptions(a.Options, b.Options) && equalLogicalRouterStaticRouteOutputPort(a.OutputPort, b.OutputPort) && equalLogicalRouterStaticRoutePolicy(a.Policy, b.Policy) && - a.RouteTable == b.RouteTable + a.RouteTable == b.RouteTable && + equalLogicalRouterStaticRouteSelectionFields(a.SelectionFields, b.SelectionFields) } func (a *LogicalRouterStaticRoute) EqualsModel(b model.Model) bool { diff --git a/go-controller/pkg/nbdb/logical_switch_port.go b/go-controller/pkg/nbdb/logical_switch_port.go index b211672bff..87994fdc72 100644 --- a/go-controller/pkg/nbdb/logical_switch_port.go +++ b/go-controller/pkg/nbdb/logical_switch_port.go @@ -21,6 +21,7 @@ type LogicalSwitchPort struct { Name string `ovsdb:"name"` Options map[string]string `ovsdb:"options"` ParentName *string `ovsdb:"parent_name"` + Peer *string `ovsdb:"peer"` PortSecurity []string `ovsdb:"port_security"` Tag *int `ovsdb:"tag"` TagRequest *int `ovsdb:"tag_request"` @@ -284,6 +285,28 @@ func equalLogicalSwitchPortParentName(a, b *string) bool { return *a == *b } +func (a *LogicalSwitchPort) GetPeer() *string { + return a.Peer +} + +func copyLogicalSwitchPortPeer(a *string) *string { + if a == nil { + return nil + } + b := *a + return &b +} + +func equalLogicalSwitchPortPeer(a, b *string) bool { + if (a == nil) != (b == nil) { + return false + } + if a == b { + return true + } + return *a == *b +} + func (a *LogicalSwitchPort) GetPortSecurity() []string { return a.PortSecurity } @@ -394,6 +417,7 @@ func (a *LogicalSwitchPort) DeepCopyInto(b *LogicalSwitchPort) { b.MirrorRules = copyLogicalSwitchPortMirrorRules(a.MirrorRules) b.Options = copyLogicalSwitchPortOptions(a.Options) b.ParentName = copyLogicalSwitchPortParentName(a.ParentName) + b.Peer = copyLogicalSwitchPortPeer(a.Peer) b.PortSecurity = copyLogicalSwitchPortPortSecurity(a.PortSecurity) b.Tag = copyLogicalSwitchPortTag(a.Tag) b.TagRequest = copyLogicalSwitchPortTagRequest(a.TagRequest) @@ -428,6 +452,7 @@ func (a *LogicalSwitchPort) Equals(b *LogicalSwitchPort) bool { a.Name == b.Name && equalLogicalSwitchPortOptions(a.Options, b.Options) && equalLogicalSwitchPortParentName(a.ParentName, b.ParentName) && + equalLogicalSwitchPortPeer(a.Peer, b.Peer) && equalLogicalSwitchPortPortSecurity(a.PortSecurity, b.PortSecurity) && equalLogicalSwitchPortTag(a.Tag, b.Tag) && equalLogicalSwitchPortTagRequest(a.TagRequest, b.TagRequest) && diff --git a/go-controller/pkg/nbdb/model.go b/go-controller/pkg/nbdb/model.go index 9fbe25db4f..07ca7e0e97 100644 --- a/go-controller/pkg/nbdb/model.go +++ b/go-controller/pkg/nbdb/model.go @@ -52,7 +52,7 @@ func FullDatabaseModel() (model.ClientDBModel, error) { var schema = `{ "name": "OVN_Northbound", - "version": "7.6.0", + "version": "7.11.0", "tables": { "ACL": { "columns": { @@ -819,6 +819,8 @@ var schema = `{ "eth_dst", "ip_src", "ip_dst", + "ipv6_src", + "ipv6_dst", "tp_src", "tp_dst" ] @@ -1026,7 +1028,8 @@ var schema = `{ [ "allow", "drop", - "reroute" + "reroute", + "jump" ] ] } @@ -1043,6 +1046,15 @@ var schema = `{ "max": "unlimited" } }, + "chain": { + "type": { + "key": { + "type": "string" + }, + "min": 0, + "max": 1 + } + }, "external_ids": { "type": { "key": { @@ -1055,6 +1067,15 @@ var schema = `{ "max": "unlimited" } }, + "jump_chain": { + "type": { + "key": { + "type": "string" + }, + "min": 0, + "max": 1 + } + }, "match": { "type": "string" }, @@ -1187,7 +1208,7 @@ var schema = `{ "key": { "type": "string" }, - "min": 1, + "min": 0, "max": "unlimited" } }, @@ -1301,6 +1322,29 @@ var schema = `{ }, "route_table": { "type": "string" + }, + "selection_fields": { + "type": { + "key": { + "type": "string", + "enum": [ + "set", + [ + "eth_src", + "eth_dst", + "ip_proto", + "ip_src", + "ip_dst", + "ipv6_src", + "ipv6_dst", + "tp_src", + "tp_dst" + ] + ] + }, + "min": 0, + "max": "unlimited" + } } } }, @@ -1532,6 +1576,15 @@ var schema = `{ "max": 1 } }, + "peer": { + "type": { + "key": { + "type": "string" + }, + "min": 0, + "max": 1 + } + }, "port_security": { "type": { "key": { @@ -2092,6 +2145,9 @@ var schema = `{ "ssl_ciphers": { "type": "string" }, + "ssl_ciphersuites": { + "type": "string" + }, "ssl_protocols": { "type": "string" } diff --git a/go-controller/pkg/nbdb/ssl.go b/go-controller/pkg/nbdb/ssl.go index 847ea8c362..0f01efc978 100644 --- a/go-controller/pkg/nbdb/ssl.go +++ b/go-controller/pkg/nbdb/ssl.go @@ -16,6 +16,7 @@ type SSL struct { ExternalIDs map[string]string `ovsdb:"external_ids"` PrivateKey string `ovsdb:"private_key"` SSLCiphers string `ovsdb:"ssl_ciphers"` + SSLCiphersuites string `ovsdb:"ssl_ciphersuites"` SSLProtocols string `ovsdb:"ssl_protocols"` } @@ -73,6 +74,10 @@ func (a *SSL) GetSSLCiphers() string { return a.SSLCiphers } +func (a *SSL) GetSSLCiphersuites() string { + return a.SSLCiphersuites +} + func (a *SSL) GetSSLProtocols() string { return a.SSLProtocols } @@ -105,6 +110,7 @@ func (a *SSL) Equals(b *SSL) bool { equalSSLExternalIDs(a.ExternalIDs, b.ExternalIDs) && a.PrivateKey == b.PrivateKey && a.SSLCiphers == b.SSLCiphers && + a.SSLCiphersuites == b.SSLCiphersuites && a.SSLProtocols == b.SSLProtocols } diff --git a/go-controller/pkg/sbdb/acl_id.go b/go-controller/pkg/sbdb/acl_id.go new file mode 100644 index 0000000000..5c62c53fe2 --- /dev/null +++ b/go-controller/pkg/sbdb/acl_id.go @@ -0,0 +1,54 @@ +// Code generated by "libovsdb.modelgen" +// DO NOT EDIT. + +package sbdb + +import "github.com/ovn-kubernetes/libovsdb/model" + +const ACLIDTable = "ACL_ID" + +// ACLID defines an object in ACL_ID table +type ACLID struct { + UUID string `ovsdb:"_uuid"` + ID int `ovsdb:"id"` +} + +func (a *ACLID) GetUUID() string { + return a.UUID +} + +func (a *ACLID) GetID() int { + return a.ID +} + +func (a *ACLID) DeepCopyInto(b *ACLID) { + *b = *a +} + +func (a *ACLID) DeepCopy() *ACLID { + b := new(ACLID) + a.DeepCopyInto(b) + return b +} + +func (a *ACLID) CloneModelInto(b model.Model) { + c := b.(*ACLID) + a.DeepCopyInto(c) +} + +func (a *ACLID) CloneModel() model.Model { + return a.DeepCopy() +} + +func (a *ACLID) Equals(b *ACLID) bool { + return a.UUID == b.UUID && + a.ID == b.ID +} + +func (a *ACLID) EqualsModel(b model.Model) bool { + c := b.(*ACLID) + return a.Equals(c) +} + +var _ model.CloneableModel = &ACLID{} +var _ model.ComparableModel = &ACLID{} diff --git a/go-controller/pkg/sbdb/advertised_route.go b/go-controller/pkg/sbdb/advertised_route.go new file mode 100644 index 0000000000..6704be7d4d --- /dev/null +++ b/go-controller/pkg/sbdb/advertised_route.go @@ -0,0 +1,124 @@ +// Code generated by "libovsdb.modelgen" +// DO NOT EDIT. + +package sbdb + +import "github.com/ovn-kubernetes/libovsdb/model" + +const AdvertisedRouteTable = "Advertised_Route" + +// AdvertisedRoute defines an object in Advertised_Route table +type AdvertisedRoute struct { + UUID string `ovsdb:"_uuid"` + Datapath string `ovsdb:"datapath"` + ExternalIDs map[string]string `ovsdb:"external_ids"` + IPPrefix string `ovsdb:"ip_prefix"` + LogicalPort string `ovsdb:"logical_port"` + TrackedPort *string `ovsdb:"tracked_port"` +} + +func (a *AdvertisedRoute) GetUUID() string { + return a.UUID +} + +func (a *AdvertisedRoute) GetDatapath() string { + return a.Datapath +} + +func (a *AdvertisedRoute) GetExternalIDs() map[string]string { + return a.ExternalIDs +} + +func copyAdvertisedRouteExternalIDs(a map[string]string) map[string]string { + if a == nil { + return nil + } + b := make(map[string]string, len(a)) + for k, v := range a { + b[k] = v + } + return b +} + +func equalAdvertisedRouteExternalIDs(a, b map[string]string) bool { + if (a == nil) != (b == nil) { + return false + } + if len(a) != len(b) { + return false + } + for k, v := range a { + if w, ok := b[k]; !ok || v != w { + return false + } + } + return true +} + +func (a *AdvertisedRoute) GetIPPrefix() string { + return a.IPPrefix +} + +func (a *AdvertisedRoute) GetLogicalPort() string { + return a.LogicalPort +} + +func (a *AdvertisedRoute) GetTrackedPort() *string { + return a.TrackedPort +} + +func copyAdvertisedRouteTrackedPort(a *string) *string { + if a == nil { + return nil + } + b := *a + return &b +} + +func equalAdvertisedRouteTrackedPort(a, b *string) bool { + if (a == nil) != (b == nil) { + return false + } + if a == b { + return true + } + return *a == *b +} + +func (a *AdvertisedRoute) DeepCopyInto(b *AdvertisedRoute) { + *b = *a + b.ExternalIDs = copyAdvertisedRouteExternalIDs(a.ExternalIDs) + b.TrackedPort = copyAdvertisedRouteTrackedPort(a.TrackedPort) +} + +func (a *AdvertisedRoute) DeepCopy() *AdvertisedRoute { + b := new(AdvertisedRoute) + a.DeepCopyInto(b) + return b +} + +func (a *AdvertisedRoute) CloneModelInto(b model.Model) { + c := b.(*AdvertisedRoute) + a.DeepCopyInto(c) +} + +func (a *AdvertisedRoute) CloneModel() model.Model { + return a.DeepCopy() +} + +func (a *AdvertisedRoute) Equals(b *AdvertisedRoute) bool { + return a.UUID == b.UUID && + a.Datapath == b.Datapath && + equalAdvertisedRouteExternalIDs(a.ExternalIDs, b.ExternalIDs) && + a.IPPrefix == b.IPPrefix && + a.LogicalPort == b.LogicalPort && + equalAdvertisedRouteTrackedPort(a.TrackedPort, b.TrackedPort) +} + +func (a *AdvertisedRoute) EqualsModel(b model.Model) bool { + c := b.(*AdvertisedRoute) + return a.Equals(c) +} + +var _ model.CloneableModel = &AdvertisedRoute{} +var _ model.ComparableModel = &AdvertisedRoute{} diff --git a/go-controller/pkg/sbdb/ecmp_nexthop.go b/go-controller/pkg/sbdb/ecmp_nexthop.go new file mode 100644 index 0000000000..2b0124a788 --- /dev/null +++ b/go-controller/pkg/sbdb/ecmp_nexthop.go @@ -0,0 +1,105 @@ +// Code generated by "libovsdb.modelgen" +// DO NOT EDIT. + +package sbdb + +import "github.com/ovn-kubernetes/libovsdb/model" + +const ECMPNexthopTable = "ECMP_Nexthop" + +// ECMPNexthop defines an object in ECMP_Nexthop table +type ECMPNexthop struct { + UUID string `ovsdb:"_uuid"` + Datapath string `ovsdb:"datapath"` + ExternalIDs map[string]string `ovsdb:"external_ids"` + MAC string `ovsdb:"mac"` + Nexthop string `ovsdb:"nexthop"` + Port string `ovsdb:"port"` +} + +func (a *ECMPNexthop) GetUUID() string { + return a.UUID +} + +func (a *ECMPNexthop) GetDatapath() string { + return a.Datapath +} + +func (a *ECMPNexthop) GetExternalIDs() map[string]string { + return a.ExternalIDs +} + +func copyECMPNexthopExternalIDs(a map[string]string) map[string]string { + if a == nil { + return nil + } + b := make(map[string]string, len(a)) + for k, v := range a { + b[k] = v + } + return b +} + +func equalECMPNexthopExternalIDs(a, b map[string]string) bool { + if (a == nil) != (b == nil) { + return false + } + if len(a) != len(b) { + return false + } + for k, v := range a { + if w, ok := b[k]; !ok || v != w { + return false + } + } + return true +} + +func (a *ECMPNexthop) GetMAC() string { + return a.MAC +} + +func (a *ECMPNexthop) GetNexthop() string { + return a.Nexthop +} + +func (a *ECMPNexthop) GetPort() string { + return a.Port +} + +func (a *ECMPNexthop) DeepCopyInto(b *ECMPNexthop) { + *b = *a + b.ExternalIDs = copyECMPNexthopExternalIDs(a.ExternalIDs) +} + +func (a *ECMPNexthop) DeepCopy() *ECMPNexthop { + b := new(ECMPNexthop) + a.DeepCopyInto(b) + return b +} + +func (a *ECMPNexthop) CloneModelInto(b model.Model) { + c := b.(*ECMPNexthop) + a.DeepCopyInto(c) +} + +func (a *ECMPNexthop) CloneModel() model.Model { + return a.DeepCopy() +} + +func (a *ECMPNexthop) Equals(b *ECMPNexthop) bool { + return a.UUID == b.UUID && + a.Datapath == b.Datapath && + equalECMPNexthopExternalIDs(a.ExternalIDs, b.ExternalIDs) && + a.MAC == b.MAC && + a.Nexthop == b.Nexthop && + a.Port == b.Port +} + +func (a *ECMPNexthop) EqualsModel(b model.Model) bool { + c := b.(*ECMPNexthop) + return a.Equals(c) +} + +var _ model.CloneableModel = &ECMPNexthop{} +var _ model.ComparableModel = &ECMPNexthop{} diff --git a/go-controller/pkg/sbdb/learned_route.go b/go-controller/pkg/sbdb/learned_route.go new file mode 100644 index 0000000000..8cab3636de --- /dev/null +++ b/go-controller/pkg/sbdb/learned_route.go @@ -0,0 +1,105 @@ +// Code generated by "libovsdb.modelgen" +// DO NOT EDIT. + +package sbdb + +import "github.com/ovn-kubernetes/libovsdb/model" + +const LearnedRouteTable = "Learned_Route" + +// LearnedRoute defines an object in Learned_Route table +type LearnedRoute struct { + UUID string `ovsdb:"_uuid"` + Datapath string `ovsdb:"datapath"` + ExternalIDs map[string]string `ovsdb:"external_ids"` + IPPrefix string `ovsdb:"ip_prefix"` + LogicalPort string `ovsdb:"logical_port"` + Nexthop string `ovsdb:"nexthop"` +} + +func (a *LearnedRoute) GetUUID() string { + return a.UUID +} + +func (a *LearnedRoute) GetDatapath() string { + return a.Datapath +} + +func (a *LearnedRoute) GetExternalIDs() map[string]string { + return a.ExternalIDs +} + +func copyLearnedRouteExternalIDs(a map[string]string) map[string]string { + if a == nil { + return nil + } + b := make(map[string]string, len(a)) + for k, v := range a { + b[k] = v + } + return b +} + +func equalLearnedRouteExternalIDs(a, b map[string]string) bool { + if (a == nil) != (b == nil) { + return false + } + if len(a) != len(b) { + return false + } + for k, v := range a { + if w, ok := b[k]; !ok || v != w { + return false + } + } + return true +} + +func (a *LearnedRoute) GetIPPrefix() string { + return a.IPPrefix +} + +func (a *LearnedRoute) GetLogicalPort() string { + return a.LogicalPort +} + +func (a *LearnedRoute) GetNexthop() string { + return a.Nexthop +} + +func (a *LearnedRoute) DeepCopyInto(b *LearnedRoute) { + *b = *a + b.ExternalIDs = copyLearnedRouteExternalIDs(a.ExternalIDs) +} + +func (a *LearnedRoute) DeepCopy() *LearnedRoute { + b := new(LearnedRoute) + a.DeepCopyInto(b) + return b +} + +func (a *LearnedRoute) CloneModelInto(b model.Model) { + c := b.(*LearnedRoute) + a.DeepCopyInto(c) +} + +func (a *LearnedRoute) CloneModel() model.Model { + return a.DeepCopy() +} + +func (a *LearnedRoute) Equals(b *LearnedRoute) bool { + return a.UUID == b.UUID && + a.Datapath == b.Datapath && + equalLearnedRouteExternalIDs(a.ExternalIDs, b.ExternalIDs) && + a.IPPrefix == b.IPPrefix && + a.LogicalPort == b.LogicalPort && + a.Nexthop == b.Nexthop +} + +func (a *LearnedRoute) EqualsModel(b model.Model) bool { + c := b.(*LearnedRoute) + return a.Equals(c) +} + +var _ model.CloneableModel = &LearnedRoute{} +var _ model.ComparableModel = &LearnedRoute{} diff --git a/go-controller/pkg/sbdb/model.go b/go-controller/pkg/sbdb/model.go index c5420638e5..0d9fe177bf 100644 --- a/go-controller/pkg/sbdb/model.go +++ b/go-controller/pkg/sbdb/model.go @@ -13,7 +13,9 @@ import ( // FullDatabaseModel returns the DatabaseModel object to be used in libovsdb func FullDatabaseModel() (model.ClientDBModel, error) { return model.NewClientDBModel("OVN_Southbound", map[string]model.Model{ + "ACL_ID": &ACLID{}, "Address_Set": &AddressSet{}, + "Advertised_Route": &AdvertisedRoute{}, "BFD": &BFD{}, "Chassis": &Chassis{}, "Chassis_Private": &ChassisPrivate{}, @@ -24,6 +26,7 @@ func FullDatabaseModel() (model.ClientDBModel, error) { "DHCPv6_Options": &DHCPv6Options{}, "DNS": &DNS{}, "Datapath_Binding": &DatapathBinding{}, + "ECMP_Nexthop": &ECMPNexthop{}, "Encap": &Encap{}, "FDB": &FDB{}, "Gateway_Chassis": &GatewayChassis{}, @@ -31,6 +34,7 @@ func FullDatabaseModel() (model.ClientDBModel, error) { "HA_Chassis_Group": &HAChassisGroup{}, "IGMP_Group": &IGMPGroup{}, "IP_Multicast": &IPMulticast{}, + "Learned_Route": &LearnedRoute{}, "Load_Balancer": &LoadBalancer{}, "Logical_DP_Group": &LogicalDPGroup{}, "Logical_Flow": &LogicalFlow{}, @@ -52,8 +56,22 @@ func FullDatabaseModel() (model.ClientDBModel, error) { var schema = `{ "name": "OVN_Southbound", - "version": "20.37.0", + "version": "20.41.0", "tables": { + "ACL_ID": { + "columns": { + "id": { + "type": { + "key": { + "type": "integer", + "minInteger": 0, + "maxInteger": 32767 + } + } + } + }, + "isRoot": true + }, "Address_Set": { "columns": { "addresses": { @@ -76,6 +94,63 @@ var schema = `{ ], "isRoot": true }, + "Advertised_Route": { + "columns": { + "datapath": { + "type": { + "key": { + "type": "uuid", + "refTable": "Datapath_Binding", + "refType": "strong" + } + } + }, + "external_ids": { + "type": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + }, + "min": 0, + "max": "unlimited" + } + }, + "ip_prefix": { + "type": "string" + }, + "logical_port": { + "type": { + "key": { + "type": "uuid", + "refTable": "Port_Binding", + "refType": "strong" + } + } + }, + "tracked_port": { + "type": { + "key": { + "type": "uuid", + "refTable": "Port_Binding", + "refType": "strong" + }, + "min": 0, + "max": 1 + } + } + }, + "indexes": [ + [ + "datapath", + "logical_port", + "ip_prefix", + "tracked_port" + ] + ], + "isRoot": true + }, "BFD": { "columns": { "chassis_name": { @@ -576,6 +651,57 @@ var schema = `{ ], "isRoot": true }, + "ECMP_Nexthop": { + "columns": { + "datapath": { + "type": { + "key": { + "type": "uuid", + "refTable": "Datapath_Binding", + "refType": "strong" + }, + "min": 1, + "max": 1 + } + }, + "external_ids": { + "type": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + }, + "min": 0, + "max": "unlimited" + } + }, + "mac": { + "type": "string" + }, + "nexthop": { + "type": "string" + }, + "port": { + "type": { + "key": { + "type": "uuid", + "refTable": "Port_Binding", + "refType": "strong" + }, + "min": 1, + "max": 1 + } + } + }, + "indexes": [ + [ + "nexthop", + "port" + ] + ], + "isRoot": true + }, "Encap": { "columns": { "chassis_name": { @@ -932,6 +1058,55 @@ var schema = `{ ], "isRoot": true }, + "Learned_Route": { + "columns": { + "datapath": { + "type": { + "key": { + "type": "uuid", + "refTable": "Datapath_Binding", + "refType": "strong" + } + } + }, + "external_ids": { + "type": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + }, + "min": 0, + "max": "unlimited" + } + }, + "ip_prefix": { + "type": "string" + }, + "logical_port": { + "type": { + "key": { + "type": "uuid", + "refTable": "Port_Binding", + "refType": "strong" + } + } + }, + "nexthop": { + "type": "string" + } + }, + "indexes": [ + [ + "datapath", + "logical_port", + "ip_prefix", + "nexthop" + ] + ], + "isRoot": true + }, "Load_Balancer": { "columns": { "datapath_group": { @@ -1741,6 +1916,9 @@ var schema = `{ "ssl_ciphers": { "type": "string" }, + "ssl_ciphersuites": { + "type": "string" + }, "ssl_protocols": { "type": "string" } diff --git a/go-controller/pkg/sbdb/ssl.go b/go-controller/pkg/sbdb/ssl.go index 08c8e641cf..eccda6dff3 100644 --- a/go-controller/pkg/sbdb/ssl.go +++ b/go-controller/pkg/sbdb/ssl.go @@ -16,6 +16,7 @@ type SSL struct { ExternalIDs map[string]string `ovsdb:"external_ids"` PrivateKey string `ovsdb:"private_key"` SSLCiphers string `ovsdb:"ssl_ciphers"` + SSLCiphersuites string `ovsdb:"ssl_ciphersuites"` SSLProtocols string `ovsdb:"ssl_protocols"` } @@ -73,6 +74,10 @@ func (a *SSL) GetSSLCiphers() string { return a.SSLCiphers } +func (a *SSL) GetSSLCiphersuites() string { + return a.SSLCiphersuites +} + func (a *SSL) GetSSLProtocols() string { return a.SSLProtocols } @@ -105,6 +110,7 @@ func (a *SSL) Equals(b *SSL) bool { equalSSLExternalIDs(a.ExternalIDs, b.ExternalIDs) && a.PrivateKey == b.PrivateKey && a.SSLCiphers == b.SSLCiphers && + a.SSLCiphersuites == b.SSLCiphersuites && a.SSLProtocols == b.SSLProtocols } From 575a08cb4e433f0a54c8a6815acaac9fef6edd31 Mon Sep 17 00:00:00 2001 From: arkadeepsen Date: Tue, 29 Jul 2025 17:59:55 +0530 Subject: [PATCH 023/115] dnsnameresolver: fix ever growing address set Signed-off-by: arkadeepsen --- go-controller/pkg/ovn/dns_name_resolver/external_dns.go | 2 +- .../pkg/ovn/dns_name_resolver/external_dns_tracker.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/go-controller/pkg/ovn/dns_name_resolver/external_dns.go b/go-controller/pkg/ovn/dns_name_resolver/external_dns.go index cd542c48e1..1f676afb88 100644 --- a/go-controller/pkg/ovn/dns_name_resolver/external_dns.go +++ b/go-controller/pkg/ovn/dns_name_resolver/external_dns.go @@ -159,7 +159,7 @@ func (extEgDNS *ExternalEgressDNS) reconcileDNSNameResolver(key string) error { addresses = append(addresses, resolvedAddress.IP) } } - err = extEgDNS.dnsTracker.addDNSName(dnsName, addresses) + err = extEgDNS.dnsTracker.addOrUpdateDNSName(dnsName, addresses) return err } diff --git a/go-controller/pkg/ovn/dns_name_resolver/external_dns_tracker.go b/go-controller/pkg/ovn/dns_name_resolver/external_dns_tracker.go index 730bd026af..b8cd861e97 100644 --- a/go-controller/pkg/ovn/dns_name_resolver/external_dns_tracker.go +++ b/go-controller/pkg/ovn/dns_name_resolver/external_dns_tracker.go @@ -59,8 +59,8 @@ func newDNSTracker(addressSetFactory addressset.AddressSetFactory, controllerNam } } -// addDNSName is called whenever a DNS name is needed to be added or updated. -func (dnsTracker *dnsTracker) addDNSName(dnsName string, addresses []string) error { +// addOrUpdateDNSName is called whenever a DNS name is needed to be added or updated. +func (dnsTracker *dnsTracker) addOrUpdateDNSName(dnsName string, addresses []string) error { dnsTracker.dnsLock.Lock() defer dnsTracker.dnsLock.Unlock() @@ -92,7 +92,7 @@ func (dnsTracker *dnsTracker) addDNSName(dnsName string, addresses []string) err addresses = filteredIPs } - if err := resolvedName.dnsAddressSet.AddAddresses(addresses); err != nil { + if err := resolvedName.dnsAddressSet.SetAddresses(addresses); err != nil { return fmt.Errorf("cannot add IPs to AddressSet for DNS name %s: %v", dnsName, err) } From 4780a5e2323ecbd5ed807085b56d5ba0547c002d Mon Sep 17 00:00:00 2001 From: arkadeepsen Date: Wed, 30 Jul 2025 21:49:37 +0530 Subject: [PATCH 024/115] dnsnameresolver: add unit test for DNSNameResolver resource update Signed-off-by: arkadeepsen --- .../dns_name_resolver/external_dns_test.go | 51 ++++++++++++++----- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/go-controller/pkg/ovn/dns_name_resolver/external_dns_test.go b/go-controller/pkg/ovn/dns_name_resolver/external_dns_test.go index 72661bd4ed..bfe050f288 100644 --- a/go-controller/pkg/ovn/dns_name_resolver/external_dns_test.go +++ b/go-controller/pkg/ovn/dns_name_resolver/external_dns_test.go @@ -52,21 +52,15 @@ func newDNSNameResolverObject(name, namespace, dnsName string, addresses []strin } func expectDNSNameWithAddresses(extEgDNS *ExternalEgressDNS, dnsName string, expectedAddresses []string) { - var resolvedName *dnsResolvedName - err := wait.PollUntilContextTimeout(context.Background(), 1*time.Second, 5*time.Minute, true, func(context.Context) (done bool, err error) { - var exists bool - resolvedName, exists = extEgDNS.getResolvedName(dnsName) + gomega.Eventually(func() []string { + resolvedName, exists := extEgDNS.getResolvedName(dnsName) if !exists { - return false, nil + return []string{} } - - return true, nil - }) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - - v4, v6 := resolvedName.dnsAddressSet.GetAddresses() - ipStrings := append(v4, v6...) - gomega.Expect(ipStrings).To(gomega.ConsistOf(expectedAddresses)) + v4, v6 := resolvedName.dnsAddressSet.GetAddresses() + ipStrings := append(v4, v6...) + return ipStrings + }).Should(gomega.ConsistOf(expectedAddresses)) } var _ = ginkgo.Describe("Egress Firewall External DNS Operations", func() { @@ -227,6 +221,37 @@ var _ = ginkgo.Describe("Egress Firewall External DNS Operations", func() { }) }) + ginkgo.Context("on dns name resolver resource update", func() { + ginkgo.It("Should update addresses for a dns name", func() { + start() + + config.IPv4Mode = true + config.IPv6Mode = true + + addresses := []string{"1.1.1.1", "2.2.2.2", "2001:0db8:85a3:0000:0000:8a2e:0370:7334"} + dnsNameResolver := newDNSNameResolverObject("dns-default", config.Kubernetes.OVNConfigNamespace, dnsName, addresses) + + _, err := fakeClient.OCPNetworkClient.NetworkV1alpha1().DNSNameResolvers(dnsNameResolver.Namespace). + Create(context.TODO(), dnsNameResolver, metav1.CreateOptions{}) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + + expectDNSNameWithAddresses(extEgDNS, dnsName, addresses) + + addresses = []string{"2.2.2.2", "3.3.3.3", "2001:0db8:85a3:0000:0000:8a2e:0370:7334", "2001:0db8:85a3:0000:0000:8a2e:0370:7335"} + var resolvedAddresses []ocpnetworkapiv1alpha1.DNSNameResolverResolvedAddress + for _, address := range addresses { + resolvedAddresses = append(resolvedAddresses, ocpnetworkapiv1alpha1.DNSNameResolverResolvedAddress{IP: address}) + } + dnsNameResolver.Status.ResolvedNames[0].ResolvedAddresses = resolvedAddresses + + _, err = fakeClient.OCPNetworkClient.NetworkV1alpha1().DNSNameResolvers(dnsNameResolver.Namespace). + Update(context.TODO(), dnsNameResolver, metav1.UpdateOptions{}) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + + expectDNSNameWithAddresses(extEgDNS, dnsName, addresses) + }) + }) + ginkgo.It("Should not delete added addresses if DNS name is still used in a namespace", func() { start() From 03ccdf9884148ef741c82205618388c4a3d4fedf Mon Sep 17 00:00:00 2001 From: nithyar Date: Tue, 29 Jul 2025 08:07:51 -0700 Subject: [PATCH 025/115] Bump ubuntu to 25.04 Signed-off-by: nithyar --- dist/images/Dockerfile.ubuntu | 4 +--- dist/images/Dockerfile.ubuntu.arm64 | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/dist/images/Dockerfile.ubuntu b/dist/images/Dockerfile.ubuntu index 10addc57d4..7fedefa624 100644 --- a/dist/images/Dockerfile.ubuntu +++ b/dist/images/Dockerfile.ubuntu @@ -8,14 +8,12 @@ # # So this file will change over time. -FROM ubuntu:24.10 +FROM ubuntu:25.04 USER root RUN apt-get update && apt-get install -y iproute2 curl software-properties-common util-linux nftables -RUN curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - - # Install OVS and OVN packages. RUN apt-get update && apt-get install -y openvswitch-switch openvswitch-common ovn-central ovn-common ovn-host diff --git a/dist/images/Dockerfile.ubuntu.arm64 b/dist/images/Dockerfile.ubuntu.arm64 index 48a408b036..3830641cf0 100644 --- a/dist/images/Dockerfile.ubuntu.arm64 +++ b/dist/images/Dockerfile.ubuntu.arm64 @@ -8,14 +8,12 @@ # # So this file will change over time. -FROM ubuntu:24.10 +FROM ubuntu:25.04 USER root RUN apt-get update && apt-get install -y iproute2 curl software-properties-common util-linux nftables -RUN curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - - # Install OVS and OVN packages. RUN apt-get update && apt-get install -y openvswitch-switch openvswitch-common ovn-central ovn-common ovn-host From 6241b2798a1947adbff2ba63f7eb4faf068cccbb Mon Sep 17 00:00:00 2001 From: arkadeepsen Date: Wed, 30 Jul 2025 12:51:35 +0530 Subject: [PATCH 026/115] dnsnameresolver: add e2e test to verify connectivity after DNS name TTL expiry Signed-off-by: arkadeepsen --- test/e2e/egress_firewall.go | 100 ++++++++++++++++++++++++++++++++++++ test/e2e/util.go | 5 ++ 2 files changed, 105 insertions(+) diff --git a/test/e2e/egress_firewall.go b/test/e2e/egress_firewall.go index abbc26b524..1805cf6a20 100644 --- a/test/e2e/egress_firewall.go +++ b/test/e2e/egress_firewall.go @@ -29,6 +29,7 @@ import ( "k8s.io/kubernetes/test/e2e/framework" e2ekubectl "k8s.io/kubernetes/test/e2e/framework/kubectl" e2enode "k8s.io/kubernetes/test/e2e/framework/node" + e2eskipper "k8s.io/kubernetes/test/e2e/framework/skipper" utilnet "k8s.io/utils/net" ) @@ -664,4 +665,103 @@ spec: table.Entry("", false), table.Entry("with chaos testing using many dnsNames", true), ) + + ginkgo.Context("with DNS name resolver", func() { + ginkgo.BeforeEach(func() { + // DNS resolution for external DNS names does not work on IPv6 clusters. Skip + // the test if DNS name resolver is not enabled or IPv4 is not supported. + if !isDNSNameResolverEnabled() { + e2eskipper.Skipf("DNS name resolver is not enabled") + return + } + if !isIPv4Supported(f.ClientSet) { + e2eskipper.Skipf("IPv4 is not supported") + return + } + }) + + getMinTTLForDNSName := func(dnsName string, srcPodName string) int { + // Get the minimum TTL for the DNS name from the nslookup output. + // Ignore the error as it will always return an error because the + // cluster local DNS lookup will fail for the following DNS names: + // - ..svc. + // - .svc.. + // - . + nslookupOutput, _ := e2ekubectl.RunKubectl(f.Namespace.Name, "exec", srcPodName, "--", "nslookup", "-debug", "-timeout=2", dnsName) + lines := strings.Split(nslookupOutput, "\n") + minTTL := -1 + for i := 0; i < len(lines); i++ { + answerLine := strings.TrimSpace(lines[i]) + // Skip lines until we find the answer line for the DNS name + if !strings.HasPrefix(answerLine, fmt.Sprintf("-> %s", dnsName)) { + continue + } + // Find the TTL line for the DNS name + for i++; i < len(lines); i++ { + ttlLine := strings.TrimSpace(lines[i]) + if strings.HasPrefix(ttlLine, "ttl =") { + // Extract TTL value + ttlParts := strings.Split(ttlLine, "ttl =") + if len(ttlParts) == 2 { + ttlStr := strings.TrimSpace(ttlParts[1]) + ttl, err := strconv.Atoi(ttlStr) + gomega.Expect(err).NotTo(gomega.HaveOccurred(), "failed to parse TTL value '%s': %v", ttlStr, err) + + // Update minimum TTL + if minTTL == -1 || ttl < minTTL { + minTTL = ttl + } + } + break + } + } + } + return minTTL + } + + ginkgo.It("Should validate that egressfirewall policy functionality for allowed DNS name", func() { + dnsName := "www.google.com" + srcPodName := "e2e-egress-fw-src-pod" + + // egress firewall crd yaml configuration + var egressFirewallConfig = fmt.Sprintf(`kind: EgressFirewall +apiVersion: k8s.ovn.org/v1 +metadata: + name: default + namespace: %s +spec: + egress: + - type: Allow + to: + dnsName: %s + - type: Deny + to: + cidrSelector: %s +`, f.Namespace.Name, dnsName, denyAllCIDR) + applyEF(egressFirewallConfig, f.Namespace.Name) + + // create the pod that will be used as the source for the connectivity test + createSrcPod(srcPodName, serverNodeInfo.name, retryInterval, retryTimeout, f) + + ginkgo.By(fmt.Sprintf("Verifying connectivity to DNS name %s is permitted", dnsName)) + url := fmt.Sprintf("https://%s", dnsName) + _, err := e2ekubectl.RunKubectl(f.Namespace.Name, "exec", srcPodName, "--", "curl", "-g", "--max-time", "5", url) + framework.ExpectNoError(err, "failed to curl DNS name %s", dnsName) + + ginkgo.By(fmt.Sprintf("Getting the minimum TTL for DNS name %s", dnsName)) + minTTL := getMinTTLForDNSName(dnsName, srcPodName) + gomega.Expect(minTTL).NotTo(gomega.Equal(-1), "failed to parse nslookup output for DNS name %s", dnsName) + framework.Logf("Minimum TTL for DNS name %s is %d", dnsName, minTTL) + + ginkgo.By(fmt.Sprintf("Waiting for the minimum TTL + 5 seconds for IP addresses of DNS name %s to be refreshed", dnsName)) + time.Sleep(time.Duration(minTTL+5) * time.Second) + + ginkgo.By(fmt.Sprintf("Verifying connectivity to DNS name %s is still permitted", dnsName)) + _, err = e2ekubectl.RunKubectl(f.Namespace.Name, "exec", srcPodName, "--", "curl", "-g", "--max-time", "5", url) + framework.ExpectNoError(err, "failed to curl DNS name %s", dnsName) + + framework.Logf("Deleting EgressFirewall in namespace %s", f.Namespace.Name) + e2ekubectl.RunKubectlOrDie(f.Namespace.Name, "delete", "egressfirewall", "default") + }) + }) }) diff --git a/test/e2e/util.go b/test/e2e/util.go index d03559e79e..8680dfcb73 100644 --- a/test/e2e/util.go +++ b/test/e2e/util.go @@ -1516,3 +1516,8 @@ func executeFileTemplate(templates *template.Template, directory, name string, d } return nil } + +func isDNSNameResolverEnabled() bool { + val, present := os.LookupEnv("OVN_ENABLE_DNSNAMERESOLVER") + return present && val == "true" +} From 8eb02f9f38dbf4e6c9f91ec4aaf4a837895d0b97 Mon Sep 17 00:00:00 2001 From: arkadeepsen Date: Wed, 30 Jul 2025 18:29:54 +0530 Subject: [PATCH 027/115] dnsnameresolver: run tests on dualstack instead of IPv6 only support Signed-off-by: arkadeepsen --- .github/workflows/test.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d9d5d40eec..da04265476 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -454,14 +454,14 @@ jobs: - {"target": "shard-conformance", "ha": "HA", "gateway-mode": "local", "ipfamily": "dualstack", "disable-snat-multiple-gws": "noSnatGW", "second-bridge": "1br", "ic": "ic-single-node-zones", "routeadvertisements": "advertise-default"} - {"target": "shard-conformance", "ha": "noHA", "gateway-mode": "shared", "ipfamily": "ipv6", "disable-snat-multiple-gws": "snatGW", "second-bridge": "1br", "ic": "ic-single-node-zones"} - {"target": "shard-conformance", "ha": "noHA", "gateway-mode": "shared", "ipfamily": "ipv4", "disable-snat-multiple-gws": "snatGW", "second-bridge": "1br", "ic": "ic-single-node-zones"} - - {"target": "control-plane", "ha": "HA", "gateway-mode": "shared", "ipfamily": "ipv6", "disable-snat-multiple-gws": "noSnatGW", "second-bridge": "1br", "ic": "ic-disabled", "dns-name-resolver": "enable-dns-name-resolver"} + - {"target": "control-plane", "ha": "HA", "gateway-mode": "shared", "ipfamily": "ipv6", "disable-snat-multiple-gws": "noSnatGW", "second-bridge": "1br", "ic": "ic-disabled"} - {"target": "control-plane", "ha": "HA", "gateway-mode": "shared", "ipfamily": "ipv4", "disable-snat-multiple-gws": "snatGW", "second-bridge": "1br", "ic": "ic-disabled", "traffic-flow-tests": "1,2,3"} - {"target": "control-plane-helm","ha": "HA", "gateway-mode": "shared", "ipfamily": "ipv4", "disable-snat-multiple-gws": "snatGW", "second-bridge": "1br", "ic": "ic-disabled", "dns-name-resolver": "enable-dns-name-resolver"} - {"target": "control-plane-helm","ha": "noHA", "gateway-mode": "shared", "ipfamily": "ipv4", "disable-snat-multiple-gws": "snatGW", "second-bridge": "1br", "ic": "ic-single-node-zones", "dns-name-resolver": "enable-dns-name-resolver"} - {"target": "control-plane", "ha": "noHA", "gateway-mode": "local", "ipfamily": "ipv4", "disable-snat-multiple-gws": "noSnatGW", "second-bridge": "1br", "ic": "ic-single-node-zones", "dns-name-resolver": "enable-dns-name-resolver"} - {"target": "control-plane", "ha": "noHA", "gateway-mode": "local", "ipfamily": "ipv6", "disable-snat-multiple-gws": "noSnatGW", "second-bridge": "1br", "ic": "ic-single-node-zones"} - {"target": "control-plane", "ha": "noHA", "gateway-mode": "shared", "ipfamily": "ipv4", "disable-snat-multiple-gws": "noSnatGW", "second-bridge": "2br", "ic": "ic-single-node-zones"} - - {"target": "control-plane", "ha": "noHA", "gateway-mode": "shared", "ipfamily": "ipv6", "disable-snat-multiple-gws": "noSnatGW", "second-bridge": "2br", "ic": "ic-single-node-zones", "dns-name-resolver": "enable-dns-name-resolver"} + - {"target": "control-plane", "ha": "noHA", "gateway-mode": "shared", "ipfamily": "ipv6", "disable-snat-multiple-gws": "noSnatGW", "second-bridge": "2br", "ic": "ic-single-node-zones"} - {"target": "multi-homing", "ha": "noHA", "gateway-mode": "local", "ipfamily": "ipv4", "disable-snat-multiple-gws": "SnatGW", "second-bridge": "1br", "ic": "ic-disabled"} - {"target": "multi-homing-helm", "ha": "HA", "gateway-mode": "shared", "ipfamily": "ipv4", "disable-snat-multiple-gws": "snatGW", "second-bridge": "1br", "ic": "ic-disabled", "network-segmentation": "enable-network-segmentation"} - {"target": "node-ip-mac-migration", "ha": "noHA", "gateway-mode": "shared", "ipfamily": "ipv6", "disable-snat-multiple-gws": "SnatGW", "second-bridge": "1br", "ic": "ic-disabled"} @@ -481,8 +481,8 @@ jobs: - {"target": "network-segmentation", "ha": "noHA", "gateway-mode": "shared", "ipfamily": "dualstack", "disable-snat-multiple-gws": "SnatGW", "second-bridge": "1br", "ic": "ic-disabled"} - {"target": "network-segmentation", "ha": "noHA", "gateway-mode": "shared", "ipfamily": "ipv4", "disable-snat-multiple-gws": "noSnatGW", "second-bridge": "1br", "ic": "ic-single-node-zones"} - {"target": "network-segmentation", "ha": "noHA", "gateway-mode": "shared", "ipfamily": "ipv6", "disable-snat-multiple-gws": "noSnatGW", "second-bridge": "1br", "ic": "ic-single-node-zones"} - - {"target": "bgp", "ha": "noHA", "gateway-mode": "local", "ipfamily": "dualstack", "disable-snat-multiple-gws": "snatGW", "second-bridge": "1br", "ic": "ic-single-node-zones", "routeadvertisements": "advertise-default", "network-segmentation": "enable-network-segmentation"} - - {"target": "bgp", "ha": "noHA", "gateway-mode": "shared", "ipfamily": "dualstack", "disable-snat-multiple-gws": "noSnatGW", "second-bridge": "1br", "ic": "ic-single-node-zones", "routeadvertisements": "advertise-default", "network-segmentation": "enable-network-segmentation"} + - {"target": "bgp", "ha": "noHA", "gateway-mode": "local", "ipfamily": "dualstack", "disable-snat-multiple-gws": "snatGW", "second-bridge": "1br", "ic": "ic-single-node-zones", "routeadvertisements": "advertise-default", "network-segmentation": "enable-network-segmentation", "dns-name-resolver": "enable-dns-name-resolver"} + - {"target": "bgp", "ha": "noHA", "gateway-mode": "shared", "ipfamily": "dualstack", "disable-snat-multiple-gws": "noSnatGW", "second-bridge": "1br", "ic": "ic-single-node-zones", "routeadvertisements": "advertise-default", "network-segmentation": "enable-network-segmentation", "dns-name-resolver": "enable-dns-name-resolver"} - {"target": "traffic-flow-test-only","ha": "noHA", "gateway-mode": "shared", "ipfamily": "ipv4", "disable-snat-multiple-gws": "noSnatGW", "second-bridge": "1br", "ic": "ic-single-node-zones", "traffic-flow-tests": "1-24", "network-segmentation": "enable-network-segmentation"} - {"target": "tools", "ha": "noHA", "gateway-mode": "local", "ipfamily": "dualstack", "disable-snat-multiple-gws": "SnatGW", "second-bridge": "1br", "ic": "ic-single-node-zones", "network-segmentation": "enable-network-segmentation"} needs: [ build-pr ] From 5180a461f483853341d4d382efd805a66d836284 Mon Sep 17 00:00:00 2001 From: Enrique Llorente Date: Wed, 25 Jun 2025 07:58:53 +0200 Subject: [PATCH 028/115] bump: network-attachment-definition-client 1.7.7 We need to bump it to allow NSE with both ipam claims reference and IPRequest. Signed-off-by: Enrique Llorente --- .../ovn-k8s-cni-overlay.go | 10 +- go-controller/go.mod | 5 +- go-controller/go.sum | 11 +- .../Masterminds/semver/v3/.gitignore | 1 + .../Masterminds/semver/v3/.golangci.yml | 27 + .../Masterminds/semver/v3/CHANGELOG.md | 214 ++++++ .../Masterminds/semver/v3/LICENSE.txt | 19 + .../github.com/Masterminds/semver/v3/Makefile | 30 + .../Masterminds/semver/v3/README.md | 258 +++++++ .../Masterminds/semver/v3/SECURITY.md | 19 + .../Masterminds/semver/v3/collection.go | 24 + .../Masterminds/semver/v3/constraints.go | 594 ++++++++++++++++ .../github.com/Masterminds/semver/v3/doc.go | 184 +++++ .../Masterminds/semver/v3/version.go | 639 ++++++++++++++++++ .../containernetworking/cni/libcni/api.go | 226 ++++++- .../containernetworking/cni/libcni/conf.go | 69 +- .../cni/libcni/multierror.go | 58 ++ .../cni/pkg/invoke/delegate.go | 25 +- .../cni/pkg/invoke/exec.go | 16 +- .../cni/pkg/invoke/os_unix.go | 1 + .../cni/pkg/ns/ns_linux.go | 50 ++ .../cni/pkg/ns/ns_windows.go | 21 + .../containernetworking/cni/pkg/skel/skel.go | 227 +++++-- .../cni/pkg/types/100/types.go | 57 +- .../containernetworking/cni/pkg/types/args.go | 4 +- .../cni/pkg/types/create/create.go | 3 + .../cni/pkg/types/types.go | 131 +++- .../cni/pkg/utils/utils.go | 6 +- .../cni/pkg/version/version.go | 9 +- .../pkg/apis/k8s.cni.cncf.io/v1/types.go | 10 +- .../pkg/utils/net-attach-def.go | 112 +++ go-controller/vendor/modules.txt | 10 +- test/e2e/go.mod | 5 +- test/e2e/go.sum | 11 +- 34 files changed, 2944 insertions(+), 142 deletions(-) create mode 100644 go-controller/vendor/github.com/Masterminds/semver/v3/.gitignore create mode 100644 go-controller/vendor/github.com/Masterminds/semver/v3/.golangci.yml create mode 100644 go-controller/vendor/github.com/Masterminds/semver/v3/CHANGELOG.md create mode 100644 go-controller/vendor/github.com/Masterminds/semver/v3/LICENSE.txt create mode 100644 go-controller/vendor/github.com/Masterminds/semver/v3/Makefile create mode 100644 go-controller/vendor/github.com/Masterminds/semver/v3/README.md create mode 100644 go-controller/vendor/github.com/Masterminds/semver/v3/SECURITY.md create mode 100644 go-controller/vendor/github.com/Masterminds/semver/v3/collection.go create mode 100644 go-controller/vendor/github.com/Masterminds/semver/v3/constraints.go create mode 100644 go-controller/vendor/github.com/Masterminds/semver/v3/doc.go create mode 100644 go-controller/vendor/github.com/Masterminds/semver/v3/version.go create mode 100644 go-controller/vendor/github.com/containernetworking/cni/libcni/multierror.go create mode 100644 go-controller/vendor/github.com/containernetworking/cni/pkg/ns/ns_linux.go create mode 100644 go-controller/vendor/github.com/containernetworking/cni/pkg/ns/ns_windows.go diff --git a/go-controller/cmd/ovn-k8s-cni-overlay/ovn-k8s-cni-overlay.go b/go-controller/cmd/ovn-k8s-cni-overlay/ovn-k8s-cni-overlay.go index 621d1e01d1..88d94faeb5 100644 --- a/go-controller/cmd/ovn-k8s-cni-overlay/ovn-k8s-cni-overlay.go +++ b/go-controller/cmd/ovn-k8s-cni-overlay/ovn-k8s-cni-overlay.go @@ -20,10 +20,12 @@ func main() { p := cni.NewCNIPlugin("") c.Action = func(_ *cli.Context) error { - skel.PluginMain( - p.CmdAdd, - p.CmdCheck, - p.CmdDel, + skel.PluginMainFuncs( + skel.CNIFuncs{ + Add: p.CmdAdd, + Check: p.CmdCheck, + Del: p.CmdDel, + }, version.All, bv.BuildString("ovn-k8s-cni-overlay")) return nil diff --git a/go-controller/go.mod b/go-controller/go.mod index 72e89c3b7a..afd8cdfe11 100644 --- a/go-controller/go.mod +++ b/go-controller/go.mod @@ -10,7 +10,7 @@ require ( github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d github.com/bhendo/go-powershell v0.0.0-20190719160123-219e7fb4e41e github.com/cenkalti/backoff/v4 v4.3.0 - github.com/containernetworking/cni v1.1.2 + github.com/containernetworking/cni v1.2.0-rc1 github.com/containernetworking/plugins v1.2.0 github.com/coreos/go-iptables v0.6.0 github.com/fsnotify/fsnotify v1.7.0 @@ -25,7 +25,7 @@ require ( github.com/k8snetworkplumbingwg/govdpa v0.1.5-0.20230926073613-07c1031aea47 github.com/k8snetworkplumbingwg/ipamclaims v0.5.0-alpha github.com/k8snetworkplumbingwg/multi-networkpolicy v1.0.1 - github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.6.0 + github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.7.7 github.com/k8snetworkplumbingwg/sriovnet v1.2.1-0.20230427090635-4929697df2dc github.com/mdlayher/arp v0.0.0-20220512170110-6706a2966875 github.com/mdlayher/ndp v1.0.1 @@ -73,6 +73,7 @@ require ( ) require ( + github.com/Masterminds/semver/v3 v3.2.1 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cenkalti/hub v1.0.1 // indirect diff --git a/go-controller/go.sum b/go-controller/go.sum index 2af1883f7e..6d72aee42e 100644 --- a/go-controller/go.sum +++ b/go-controller/go.sum @@ -55,6 +55,8 @@ github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBp github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/JacobTanenbaum/arping v0.0.0-20240209152419-3987db83bd51/go.mod h1:aJbELhR92bSk7tp79AWM/ftfc90EfEi2bQJrbBFOsPw= +github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= +github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.4.16-0.20201130162521-d1ffc52c7331/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= @@ -199,8 +201,8 @@ github.com/containerd/zfs v1.0.0/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNR github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= github.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= -github.com/containernetworking/cni v1.1.2 h1:wtRGZVv7olUHMOqouPpn3cXJWpJgM6+EUl31EQbXALQ= -github.com/containernetworking/cni v1.1.2/go.mod h1:sDpYKmGVENF3s6uvMvGgldDWeG8dMxakj/u+i9ht9vw= +github.com/containernetworking/cni v1.2.0-rc1 h1:AKI3+pXtgY4PDLN9+50o9IaywWVuey0Jkw3Lvzp0HCY= +github.com/containernetworking/cni v1.2.0-rc1/go.mod h1:Lt0TQcZQVDju64fYxUhDziTgXCDe3Olzi9I4zZJLWHg= github.com/containernetworking/plugins v0.8.6/go.mod h1:qnw5mN19D8fIwkqW7oHHYDHVlzhJpcY6TQxn/fUyDDM= github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8= github.com/containernetworking/plugins v1.2.0 h1:SWgg3dQG1yzUo4d9iD8cwSVh1VqI+bP7mkPDoSfP9VU= @@ -498,8 +500,8 @@ github.com/k8snetworkplumbingwg/ipamclaims v0.5.0-alpha h1:b3iHeks/KTzhG2dNanaUZ github.com/k8snetworkplumbingwg/ipamclaims v0.5.0-alpha/go.mod h1:MGaMX1tJ7MlHDee4/xmqp3guQh+eDiuCLAauqD9K11Q= github.com/k8snetworkplumbingwg/multi-networkpolicy v1.0.1 h1:Egj1hEVYNXWFlKpgzAXxe/2o8VNiVcAJLrKzlinILQo= github.com/k8snetworkplumbingwg/multi-networkpolicy v1.0.1/go.mod h1:kEJ4WM849yNmXekuSXLRwb+LaZ9usC06O8JgoAIq+f4= -github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.6.0 h1:BT3ghAY0q7lWib9rz+tVXDFkm27dJV6SLCn7TunZwo4= -github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.6.0/go.mod h1:wxt2YWRVItDtaQmVSmaN5ubE2L1c9CiNoHQwSJnM8Ko= +github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.7.7 h1:z4P744DR+PIpkjwXSEc6TvN3L6LVzmUquFgmNm8wSUc= +github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.7.7/go.mod h1:CM7HAH5PNuIsqjMN0fGc1ydM74Uj+0VZFhob620nklw= github.com/k8snetworkplumbingwg/sriovnet v1.2.1-0.20230427090635-4929697df2dc h1:v6+jUd70AayPbIRgTYUNpnBLG5cBPTY0+10y80CZeMk= github.com/k8snetworkplumbingwg/sriovnet v1.2.1-0.20230427090635-4929697df2dc/go.mod h1:jyWzGe6ZtYiPq6ih6aXCOy6mZ49Y9mNyBOLBBXnli+k= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -603,7 +605,6 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg= github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= diff --git a/go-controller/vendor/github.com/Masterminds/semver/v3/.gitignore b/go-controller/vendor/github.com/Masterminds/semver/v3/.gitignore new file mode 100644 index 0000000000..6b061e6174 --- /dev/null +++ b/go-controller/vendor/github.com/Masterminds/semver/v3/.gitignore @@ -0,0 +1 @@ +_fuzz/ \ No newline at end of file diff --git a/go-controller/vendor/github.com/Masterminds/semver/v3/.golangci.yml b/go-controller/vendor/github.com/Masterminds/semver/v3/.golangci.yml new file mode 100644 index 0000000000..fbc6332592 --- /dev/null +++ b/go-controller/vendor/github.com/Masterminds/semver/v3/.golangci.yml @@ -0,0 +1,27 @@ +run: + deadline: 2m + +linters: + disable-all: true + enable: + - misspell + - govet + - staticcheck + - errcheck + - unparam + - ineffassign + - nakedret + - gocyclo + - dupl + - goimports + - revive + - gosec + - gosimple + - typecheck + - unused + +linters-settings: + gofmt: + simplify: true + dupl: + threshold: 600 diff --git a/go-controller/vendor/github.com/Masterminds/semver/v3/CHANGELOG.md b/go-controller/vendor/github.com/Masterminds/semver/v3/CHANGELOG.md new file mode 100644 index 0000000000..f12626423a --- /dev/null +++ b/go-controller/vendor/github.com/Masterminds/semver/v3/CHANGELOG.md @@ -0,0 +1,214 @@ +# Changelog + +## 3.2.0 (2022-11-28) + +### Added + +- #190: Added text marshaling and unmarshaling +- #167: Added JSON marshalling for constraints (thanks @SimonTheLeg) +- #173: Implement encoding.TextMarshaler and encoding.TextUnmarshaler on Version (thanks @MarkRosemaker) +- #179: Added New() version constructor (thanks @kazhuravlev) + +### Changed + +- #182/#183: Updated CI testing setup + +### Fixed + +- #186: Fixing issue where validation of constraint section gave false positives +- #176: Fix constraints check with *-0 (thanks @mtt0) +- #181: Fixed Caret operator (^) gives unexpected results when the minor version in constraint is 0 (thanks @arshchimni) +- #161: Fixed godoc (thanks @afirth) + +## 3.1.1 (2020-11-23) + +### Fixed + +- #158: Fixed issue with generated regex operation order that could cause problem + +## 3.1.0 (2020-04-15) + +### Added + +- #131: Add support for serializing/deserializing SQL (thanks @ryancurrah) + +### Changed + +- #148: More accurate validation messages on constraints + +## 3.0.3 (2019-12-13) + +### Fixed + +- #141: Fixed issue with <= comparison + +## 3.0.2 (2019-11-14) + +### Fixed + +- #134: Fixed broken constraint checking with ^0.0 (thanks @krmichelos) + +## 3.0.1 (2019-09-13) + +### Fixed + +- #125: Fixes issue with module path for v3 + +## 3.0.0 (2019-09-12) + +This is a major release of the semver package which includes API changes. The Go +API is compatible with ^1. The Go API was not changed because many people are using +`go get` without Go modules for their applications and API breaking changes cause +errors which we have or would need to support. + +The changes in this release are the handling based on the data passed into the +functions. These are described in the added and changed sections below. + +### Added + +- StrictNewVersion function. This is similar to NewVersion but will return an + error if the version passed in is not a strict semantic version. For example, + 1.2.3 would pass but v1.2.3 or 1.2 would fail because they are not strictly + speaking semantic versions. This function is faster, performs fewer operations, + and uses fewer allocations than NewVersion. +- Fuzzing has been performed on NewVersion, StrictNewVersion, and NewConstraint. + The Makefile contains the operations used. For more information on you can start + on Wikipedia at https://en.wikipedia.org/wiki/Fuzzing +- Now using Go modules + +### Changed + +- NewVersion has proper prerelease and metadata validation with error messages + to signal an issue with either of them +- ^ now operates using a similar set of rules to npm/js and Rust/Cargo. If the + version is >=1 the ^ ranges works the same as v1. For major versions of 0 the + rules have changed. The minor version is treated as the stable version unless + a patch is specified and then it is equivalent to =. One difference from npm/js + is that prereleases there are only to a specific version (e.g. 1.2.3). + Prereleases here look over multiple versions and follow semantic version + ordering rules. This pattern now follows along with the expected and requested + handling of this packaged by numerous users. + +## 1.5.0 (2019-09-11) + +### Added + +- #103: Add basic fuzzing for `NewVersion()` (thanks @jesse-c) + +### Changed + +- #82: Clarify wildcard meaning in range constraints and update tests for it (thanks @greysteil) +- #83: Clarify caret operator range for pre-1.0.0 dependencies (thanks @greysteil) +- #72: Adding docs comment pointing to vert for a cli +- #71: Update the docs on pre-release comparator handling +- #89: Test with new go versions (thanks @thedevsaddam) +- #87: Added $ to ValidPrerelease for better validation (thanks @jeremycarroll) + +### Fixed + +- #78: Fix unchecked error in example code (thanks @ravron) +- #70: Fix the handling of pre-releases and the 0.0.0 release edge case +- #97: Fixed copyright file for proper display on GitHub +- #107: Fix handling prerelease when sorting alphanum and num +- #109: Fixed where Validate sometimes returns wrong message on error + +## 1.4.2 (2018-04-10) + +### Changed + +- #72: Updated the docs to point to vert for a console appliaction +- #71: Update the docs on pre-release comparator handling + +### Fixed + +- #70: Fix the handling of pre-releases and the 0.0.0 release edge case + +## 1.4.1 (2018-04-02) + +### Fixed + +- Fixed #64: Fix pre-release precedence issue (thanks @uudashr) + +## 1.4.0 (2017-10-04) + +### Changed + +- #61: Update NewVersion to parse ints with a 64bit int size (thanks @zknill) + +## 1.3.1 (2017-07-10) + +### Fixed + +- Fixed #57: number comparisons in prerelease sometimes inaccurate + +## 1.3.0 (2017-05-02) + +### Added + +- #45: Added json (un)marshaling support (thanks @mh-cbon) +- Stability marker. See https://masterminds.github.io/stability/ + +### Fixed + +- #51: Fix handling of single digit tilde constraint (thanks @dgodd) + +### Changed + +- #55: The godoc icon moved from png to svg + +## 1.2.3 (2017-04-03) + +### Fixed + +- #46: Fixed 0.x.x and 0.0.x in constraints being treated as * + +## Release 1.2.2 (2016-12-13) + +### Fixed + +- #34: Fixed issue where hyphen range was not working with pre-release parsing. + +## Release 1.2.1 (2016-11-28) + +### Fixed + +- #24: Fixed edge case issue where constraint "> 0" does not handle "0.0.1-alpha" + properly. + +## Release 1.2.0 (2016-11-04) + +### Added + +- #20: Added MustParse function for versions (thanks @adamreese) +- #15: Added increment methods on versions (thanks @mh-cbon) + +### Fixed + +- Issue #21: Per the SemVer spec (section 9) a pre-release is unstable and + might not satisfy the intended compatibility. The change here ignores pre-releases + on constraint checks (e.g., ~ or ^) when a pre-release is not part of the + constraint. For example, `^1.2.3` will ignore pre-releases while + `^1.2.3-alpha` will include them. + +## Release 1.1.1 (2016-06-30) + +### Changed + +- Issue #9: Speed up version comparison performance (thanks @sdboyer) +- Issue #8: Added benchmarks (thanks @sdboyer) +- Updated Go Report Card URL to new location +- Updated Readme to add code snippet formatting (thanks @mh-cbon) +- Updating tagging to v[SemVer] structure for compatibility with other tools. + +## Release 1.1.0 (2016-03-11) + +- Issue #2: Implemented validation to provide reasons a versions failed a + constraint. + +## Release 1.0.1 (2015-12-31) + +- Fixed #1: * constraint failing on valid versions. + +## Release 1.0.0 (2015-10-20) + +- Initial release diff --git a/go-controller/vendor/github.com/Masterminds/semver/v3/LICENSE.txt b/go-controller/vendor/github.com/Masterminds/semver/v3/LICENSE.txt new file mode 100644 index 0000000000..9ff7da9c48 --- /dev/null +++ b/go-controller/vendor/github.com/Masterminds/semver/v3/LICENSE.txt @@ -0,0 +1,19 @@ +Copyright (C) 2014-2019, Matt Butcher and Matt Farina + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/go-controller/vendor/github.com/Masterminds/semver/v3/Makefile b/go-controller/vendor/github.com/Masterminds/semver/v3/Makefile new file mode 100644 index 0000000000..0e7b5c7138 --- /dev/null +++ b/go-controller/vendor/github.com/Masterminds/semver/v3/Makefile @@ -0,0 +1,30 @@ +GOPATH=$(shell go env GOPATH) +GOLANGCI_LINT=$(GOPATH)/bin/golangci-lint + +.PHONY: lint +lint: $(GOLANGCI_LINT) + @echo "==> Linting codebase" + @$(GOLANGCI_LINT) run + +.PHONY: test +test: + @echo "==> Running tests" + GO111MODULE=on go test -v + +.PHONY: test-cover +test-cover: + @echo "==> Running Tests with coverage" + GO111MODULE=on go test -cover . + +.PHONY: fuzz +fuzz: + @echo "==> Running Fuzz Tests" + go test -fuzz=FuzzNewVersion -fuzztime=15s . + go test -fuzz=FuzzStrictNewVersion -fuzztime=15s . + go test -fuzz=FuzzNewConstraint -fuzztime=15s . + +$(GOLANGCI_LINT): + # Install golangci-lint. The configuration for it is in the .golangci.yml + # file in the root of the repository + echo ${GOPATH} + curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(GOPATH)/bin v1.17.1 diff --git a/go-controller/vendor/github.com/Masterminds/semver/v3/README.md b/go-controller/vendor/github.com/Masterminds/semver/v3/README.md new file mode 100644 index 0000000000..eab8cac3b7 --- /dev/null +++ b/go-controller/vendor/github.com/Masterminds/semver/v3/README.md @@ -0,0 +1,258 @@ +# SemVer + +The `semver` package provides the ability to work with [Semantic Versions](http://semver.org) in Go. Specifically it provides the ability to: + +* Parse semantic versions +* Sort semantic versions +* Check if a semantic version fits within a set of constraints +* Optionally work with a `v` prefix + +[![Stability: +Active](https://masterminds.github.io/stability/active.svg)](https://masterminds.github.io/stability/active.html) +[![](https://github.com/Masterminds/semver/workflows/Tests/badge.svg)](https://github.com/Masterminds/semver/actions) +[![GoDoc](https://img.shields.io/static/v1?label=godoc&message=reference&color=blue)](https://pkg.go.dev/github.com/Masterminds/semver/v3) +[![Go Report Card](https://goreportcard.com/badge/github.com/Masterminds/semver)](https://goreportcard.com/report/github.com/Masterminds/semver) + +If you are looking for a command line tool for version comparisons please see +[vert](https://github.com/Masterminds/vert) which uses this library. + +## Package Versions + +Note, import `github.com/github.com/Masterminds/semver/v3` to use the latest version. + +There are three major versions fo the `semver` package. + +* 3.x.x is the stable and active version. This version is focused on constraint + compatibility for range handling in other tools from other languages. It has + a similar API to the v1 releases. The development of this version is on the master + branch. The documentation for this version is below. +* 2.x was developed primarily for [dep](https://github.com/golang/dep). There are + no tagged releases and the development was performed by [@sdboyer](https://github.com/sdboyer). + There are API breaking changes from v1. This version lives on the [2.x branch](https://github.com/Masterminds/semver/tree/2.x). +* 1.x.x is the original release. It is no longer maintained. You should use the + v3 release instead. You can read the documentation for the 1.x.x release + [here](https://github.com/Masterminds/semver/blob/release-1/README.md). + +## Parsing Semantic Versions + +There are two functions that can parse semantic versions. The `StrictNewVersion` +function only parses valid version 2 semantic versions as outlined in the +specification. The `NewVersion` function attempts to coerce a version into a +semantic version and parse it. For example, if there is a leading v or a version +listed without all 3 parts (e.g. `v1.2`) it will attempt to coerce it into a valid +semantic version (e.g., 1.2.0). In both cases a `Version` object is returned +that can be sorted, compared, and used in constraints. + +When parsing a version an error is returned if there is an issue parsing the +version. For example, + + v, err := semver.NewVersion("1.2.3-beta.1+build345") + +The version object has methods to get the parts of the version, compare it to +other versions, convert the version back into a string, and get the original +string. Getting the original string is useful if the semantic version was coerced +into a valid form. + +## Sorting Semantic Versions + +A set of versions can be sorted using the `sort` package from the standard library. +For example, + +```go +raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",} +vs := make([]*semver.Version, len(raw)) +for i, r := range raw { + v, err := semver.NewVersion(r) + if err != nil { + t.Errorf("Error parsing version: %s", err) + } + + vs[i] = v +} + +sort.Sort(semver.Collection(vs)) +``` + +## Checking Version Constraints + +There are two methods for comparing versions. One uses comparison methods on +`Version` instances and the other uses `Constraints`. There are some important +differences to notes between these two methods of comparison. + +1. When two versions are compared using functions such as `Compare`, `LessThan`, + and others it will follow the specification and always include prereleases + within the comparison. It will provide an answer that is valid with the + comparison section of the spec at https://semver.org/#spec-item-11 +2. When constraint checking is used for checks or validation it will follow a + different set of rules that are common for ranges with tools like npm/js + and Rust/Cargo. This includes considering prereleases to be invalid if the + ranges does not include one. If you want to have it include pre-releases a + simple solution is to include `-0` in your range. +3. Constraint ranges can have some complex rules including the shorthand use of + ~ and ^. For more details on those see the options below. + +There are differences between the two methods or checking versions because the +comparison methods on `Version` follow the specification while comparison ranges +are not part of the specification. Different packages and tools have taken it +upon themselves to come up with range rules. This has resulted in differences. +For example, npm/js and Cargo/Rust follow similar patterns while PHP has a +different pattern for ^. The comparison features in this package follow the +npm/js and Cargo/Rust lead because applications using it have followed similar +patters with their versions. + +Checking a version against version constraints is one of the most featureful +parts of the package. + +```go +c, err := semver.NewConstraint(">= 1.2.3") +if err != nil { + // Handle constraint not being parsable. +} + +v, err := semver.NewVersion("1.3") +if err != nil { + // Handle version not being parsable. +} +// Check if the version meets the constraints. The a variable will be true. +a := c.Check(v) +``` + +### Basic Comparisons + +There are two elements to the comparisons. First, a comparison string is a list +of space or comma separated AND comparisons. These are then separated by || (OR) +comparisons. For example, `">= 1.2 < 3.0.0 || >= 4.2.3"` is looking for a +comparison that's greater than or equal to 1.2 and less than 3.0.0 or is +greater than or equal to 4.2.3. + +The basic comparisons are: + +* `=`: equal (aliased to no operator) +* `!=`: not equal +* `>`: greater than +* `<`: less than +* `>=`: greater than or equal to +* `<=`: less than or equal to + +### Working With Prerelease Versions + +Pre-releases, for those not familiar with them, are used for software releases +prior to stable or generally available releases. Examples of prereleases include +development, alpha, beta, and release candidate releases. A prerelease may be +a version such as `1.2.3-beta.1` while the stable release would be `1.2.3`. In the +order of precedence, prereleases come before their associated releases. In this +example `1.2.3-beta.1 < 1.2.3`. + +According to the Semantic Version specification prereleases may not be +API compliant with their release counterpart. It says, + +> A pre-release version indicates that the version is unstable and might not satisfy the intended compatibility requirements as denoted by its associated normal version. + +SemVer comparisons using constraints without a prerelease comparator will skip +prerelease versions. For example, `>=1.2.3` will skip prereleases when looking +at a list of releases while `>=1.2.3-0` will evaluate and find prereleases. + +The reason for the `0` as a pre-release version in the example comparison is +because pre-releases can only contain ASCII alphanumerics and hyphens (along with +`.` separators), per the spec. Sorting happens in ASCII sort order, again per the +spec. The lowest character is a `0` in ASCII sort order +(see an [ASCII Table](http://www.asciitable.com/)) + +Understanding ASCII sort ordering is important because A-Z comes before a-z. That +means `>=1.2.3-BETA` will return `1.2.3-alpha`. What you might expect from case +sensitivity doesn't apply here. This is due to ASCII sort ordering which is what +the spec specifies. + +### Hyphen Range Comparisons + +There are multiple methods to handle ranges and the first is hyphens ranges. +These look like: + +* `1.2 - 1.4.5` which is equivalent to `>= 1.2 <= 1.4.5` +* `2.3.4 - 4.5` which is equivalent to `>= 2.3.4 <= 4.5` + +### Wildcards In Comparisons + +The `x`, `X`, and `*` characters can be used as a wildcard character. This works +for all comparison operators. When used on the `=` operator it falls +back to the patch level comparison (see tilde below). For example, + +* `1.2.x` is equivalent to `>= 1.2.0, < 1.3.0` +* `>= 1.2.x` is equivalent to `>= 1.2.0` +* `<= 2.x` is equivalent to `< 3` +* `*` is equivalent to `>= 0.0.0` + +### Tilde Range Comparisons (Patch) + +The tilde (`~`) comparison operator is for patch level ranges when a minor +version is specified and major level changes when the minor number is missing. +For example, + +* `~1.2.3` is equivalent to `>= 1.2.3, < 1.3.0` +* `~1` is equivalent to `>= 1, < 2` +* `~2.3` is equivalent to `>= 2.3, < 2.4` +* `~1.2.x` is equivalent to `>= 1.2.0, < 1.3.0` +* `~1.x` is equivalent to `>= 1, < 2` + +### Caret Range Comparisons (Major) + +The caret (`^`) comparison operator is for major level changes once a stable +(1.0.0) release has occurred. Prior to a 1.0.0 release the minor versions acts +as the API stability level. This is useful when comparisons of API versions as a +major change is API breaking. For example, + +* `^1.2.3` is equivalent to `>= 1.2.3, < 2.0.0` +* `^1.2.x` is equivalent to `>= 1.2.0, < 2.0.0` +* `^2.3` is equivalent to `>= 2.3, < 3` +* `^2.x` is equivalent to `>= 2.0.0, < 3` +* `^0.2.3` is equivalent to `>=0.2.3 <0.3.0` +* `^0.2` is equivalent to `>=0.2.0 <0.3.0` +* `^0.0.3` is equivalent to `>=0.0.3 <0.0.4` +* `^0.0` is equivalent to `>=0.0.0 <0.1.0` +* `^0` is equivalent to `>=0.0.0 <1.0.0` + +## Validation + +In addition to testing a version against a constraint, a version can be validated +against a constraint. When validation fails a slice of errors containing why a +version didn't meet the constraint is returned. For example, + +```go +c, err := semver.NewConstraint("<= 1.2.3, >= 1.4") +if err != nil { + // Handle constraint not being parseable. +} + +v, err := semver.NewVersion("1.3") +if err != nil { + // Handle version not being parseable. +} + +// Validate a version against a constraint. +a, msgs := c.Validate(v) +// a is false +for _, m := range msgs { + fmt.Println(m) + + // Loops over the errors which would read + // "1.3 is greater than 1.2.3" + // "1.3 is less than 1.4" +} +``` + +## Contribute + +If you find an issue or want to contribute please file an [issue](https://github.com/Masterminds/semver/issues) +or [create a pull request](https://github.com/Masterminds/semver/pulls). + +## Security + +Security is an important consideration for this project. The project currently +uses the following tools to help discover security issues: + +* [CodeQL](https://github.com/Masterminds/semver) +* [gosec](https://github.com/securego/gosec) +* Daily Fuzz testing + +If you believe you have found a security vulnerability you can privately disclose +it through the [GitHub security page](https://github.com/Masterminds/semver/security). diff --git a/go-controller/vendor/github.com/Masterminds/semver/v3/SECURITY.md b/go-controller/vendor/github.com/Masterminds/semver/v3/SECURITY.md new file mode 100644 index 0000000000..a30a66b1f7 --- /dev/null +++ b/go-controller/vendor/github.com/Masterminds/semver/v3/SECURITY.md @@ -0,0 +1,19 @@ +# Security Policy + +## Supported Versions + +The following versions of semver are currently supported: + +| Version | Supported | +| ------- | ------------------ | +| 3.x | :white_check_mark: | +| 2.x | :x: | +| 1.x | :x: | + +Fixes are only released for the latest minor version in the form of a patch release. + +## Reporting a Vulnerability + +You can privately disclose a vulnerability through GitHubs +[private vulnerability reporting](https://github.com/Masterminds/semver/security/advisories) +mechanism. diff --git a/go-controller/vendor/github.com/Masterminds/semver/v3/collection.go b/go-controller/vendor/github.com/Masterminds/semver/v3/collection.go new file mode 100644 index 0000000000..a78235895f --- /dev/null +++ b/go-controller/vendor/github.com/Masterminds/semver/v3/collection.go @@ -0,0 +1,24 @@ +package semver + +// Collection is a collection of Version instances and implements the sort +// interface. See the sort package for more details. +// https://golang.org/pkg/sort/ +type Collection []*Version + +// Len returns the length of a collection. The number of Version instances +// on the slice. +func (c Collection) Len() int { + return len(c) +} + +// Less is needed for the sort interface to compare two Version objects on the +// slice. If checks if one is less than the other. +func (c Collection) Less(i, j int) bool { + return c[i].LessThan(c[j]) +} + +// Swap is needed for the sort interface to replace the Version objects +// at two different positions in the slice. +func (c Collection) Swap(i, j int) { + c[i], c[j] = c[j], c[i] +} diff --git a/go-controller/vendor/github.com/Masterminds/semver/v3/constraints.go b/go-controller/vendor/github.com/Masterminds/semver/v3/constraints.go new file mode 100644 index 0000000000..8461c7ed90 --- /dev/null +++ b/go-controller/vendor/github.com/Masterminds/semver/v3/constraints.go @@ -0,0 +1,594 @@ +package semver + +import ( + "bytes" + "errors" + "fmt" + "regexp" + "strings" +) + +// Constraints is one or more constraint that a semantic version can be +// checked against. +type Constraints struct { + constraints [][]*constraint +} + +// NewConstraint returns a Constraints instance that a Version instance can +// be checked against. If there is a parse error it will be returned. +func NewConstraint(c string) (*Constraints, error) { + + // Rewrite - ranges into a comparison operation. + c = rewriteRange(c) + + ors := strings.Split(c, "||") + or := make([][]*constraint, len(ors)) + for k, v := range ors { + + // TODO: Find a way to validate and fetch all the constraints in a simpler form + + // Validate the segment + if !validConstraintRegex.MatchString(v) { + return nil, fmt.Errorf("improper constraint: %s", v) + } + + cs := findConstraintRegex.FindAllString(v, -1) + if cs == nil { + cs = append(cs, v) + } + result := make([]*constraint, len(cs)) + for i, s := range cs { + pc, err := parseConstraint(s) + if err != nil { + return nil, err + } + + result[i] = pc + } + or[k] = result + } + + o := &Constraints{constraints: or} + return o, nil +} + +// Check tests if a version satisfies the constraints. +func (cs Constraints) Check(v *Version) bool { + // TODO(mattfarina): For v4 of this library consolidate the Check and Validate + // functions as the underlying functions make that possible now. + // loop over the ORs and check the inner ANDs + for _, o := range cs.constraints { + joy := true + for _, c := range o { + if check, _ := c.check(v); !check { + joy = false + break + } + } + + if joy { + return true + } + } + + return false +} + +// Validate checks if a version satisfies a constraint. If not a slice of +// reasons for the failure are returned in addition to a bool. +func (cs Constraints) Validate(v *Version) (bool, []error) { + // loop over the ORs and check the inner ANDs + var e []error + + // Capture the prerelease message only once. When it happens the first time + // this var is marked + var prerelesase bool + for _, o := range cs.constraints { + joy := true + for _, c := range o { + // Before running the check handle the case there the version is + // a prerelease and the check is not searching for prereleases. + if c.con.pre == "" && v.pre != "" { + if !prerelesase { + em := fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) + e = append(e, em) + prerelesase = true + } + joy = false + + } else { + + if _, err := c.check(v); err != nil { + e = append(e, err) + joy = false + } + } + } + + if joy { + return true, []error{} + } + } + + return false, e +} + +func (cs Constraints) String() string { + buf := make([]string, len(cs.constraints)) + var tmp bytes.Buffer + + for k, v := range cs.constraints { + tmp.Reset() + vlen := len(v) + for kk, c := range v { + tmp.WriteString(c.string()) + + // Space separate the AND conditions + if vlen > 1 && kk < vlen-1 { + tmp.WriteString(" ") + } + } + buf[k] = tmp.String() + } + + return strings.Join(buf, " || ") +} + +// UnmarshalText implements the encoding.TextUnmarshaler interface. +func (cs *Constraints) UnmarshalText(text []byte) error { + temp, err := NewConstraint(string(text)) + if err != nil { + return err + } + + *cs = *temp + + return nil +} + +// MarshalText implements the encoding.TextMarshaler interface. +func (cs Constraints) MarshalText() ([]byte, error) { + return []byte(cs.String()), nil +} + +var constraintOps map[string]cfunc +var constraintRegex *regexp.Regexp +var constraintRangeRegex *regexp.Regexp + +// Used to find individual constraints within a multi-constraint string +var findConstraintRegex *regexp.Regexp + +// Used to validate an segment of ANDs is valid +var validConstraintRegex *regexp.Regexp + +const cvRegex string = `v?([0-9|x|X|\*]+)(\.[0-9|x|X|\*]+)?(\.[0-9|x|X|\*]+)?` + + `(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` + + `(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` + +func init() { + constraintOps = map[string]cfunc{ + "": constraintTildeOrEqual, + "=": constraintTildeOrEqual, + "!=": constraintNotEqual, + ">": constraintGreaterThan, + "<": constraintLessThan, + ">=": constraintGreaterThanEqual, + "=>": constraintGreaterThanEqual, + "<=": constraintLessThanEqual, + "=<": constraintLessThanEqual, + "~": constraintTilde, + "~>": constraintTilde, + "^": constraintCaret, + } + + ops := `=||!=|>|<|>=|=>|<=|=<|~|~>|\^` + + constraintRegex = regexp.MustCompile(fmt.Sprintf( + `^\s*(%s)\s*(%s)\s*$`, + ops, + cvRegex)) + + constraintRangeRegex = regexp.MustCompile(fmt.Sprintf( + `\s*(%s)\s+-\s+(%s)\s*`, + cvRegex, cvRegex)) + + findConstraintRegex = regexp.MustCompile(fmt.Sprintf( + `(%s)\s*(%s)`, + ops, + cvRegex)) + + // The first time a constraint shows up will look slightly different from + // future times it shows up due to a leading space or comma in a given + // string. + validConstraintRegex = regexp.MustCompile(fmt.Sprintf( + `^(\s*(%s)\s*(%s)\s*)((?:\s+|,\s*)(%s)\s*(%s)\s*)*$`, + ops, + cvRegex, + ops, + cvRegex)) +} + +// An individual constraint +type constraint struct { + // The version used in the constraint check. For example, if a constraint + // is '<= 2.0.0' the con a version instance representing 2.0.0. + con *Version + + // The original parsed version (e.g., 4.x from != 4.x) + orig string + + // The original operator for the constraint + origfunc string + + // When an x is used as part of the version (e.g., 1.x) + minorDirty bool + dirty bool + patchDirty bool +} + +// Check if a version meets the constraint +func (c *constraint) check(v *Version) (bool, error) { + return constraintOps[c.origfunc](v, c) +} + +// String prints an individual constraint into a string +func (c *constraint) string() string { + return c.origfunc + c.orig +} + +type cfunc func(v *Version, c *constraint) (bool, error) + +func parseConstraint(c string) (*constraint, error) { + if len(c) > 0 { + m := constraintRegex.FindStringSubmatch(c) + if m == nil { + return nil, fmt.Errorf("improper constraint: %s", c) + } + + cs := &constraint{ + orig: m[2], + origfunc: m[1], + } + + ver := m[2] + minorDirty := false + patchDirty := false + dirty := false + if isX(m[3]) || m[3] == "" { + ver = fmt.Sprintf("0.0.0%s", m[6]) + dirty = true + } else if isX(strings.TrimPrefix(m[4], ".")) || m[4] == "" { + minorDirty = true + dirty = true + ver = fmt.Sprintf("%s.0.0%s", m[3], m[6]) + } else if isX(strings.TrimPrefix(m[5], ".")) || m[5] == "" { + dirty = true + patchDirty = true + ver = fmt.Sprintf("%s%s.0%s", m[3], m[4], m[6]) + } + + con, err := NewVersion(ver) + if err != nil { + + // The constraintRegex should catch any regex parsing errors. So, + // we should never get here. + return nil, errors.New("constraint Parser Error") + } + + cs.con = con + cs.minorDirty = minorDirty + cs.patchDirty = patchDirty + cs.dirty = dirty + + return cs, nil + } + + // The rest is the special case where an empty string was passed in which + // is equivalent to * or >=0.0.0 + con, err := StrictNewVersion("0.0.0") + if err != nil { + + // The constraintRegex should catch any regex parsing errors. So, + // we should never get here. + return nil, errors.New("constraint Parser Error") + } + + cs := &constraint{ + con: con, + orig: c, + origfunc: "", + minorDirty: false, + patchDirty: false, + dirty: true, + } + return cs, nil +} + +// Constraint functions +func constraintNotEqual(v *Version, c *constraint) (bool, error) { + if c.dirty { + + // If there is a pre-release on the version but the constraint isn't looking + // for them assume that pre-releases are not compatible. See issue 21 for + // more details. + if v.Prerelease() != "" && c.con.Prerelease() == "" { + return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) + } + + if c.con.Major() != v.Major() { + return true, nil + } + if c.con.Minor() != v.Minor() && !c.minorDirty { + return true, nil + } else if c.minorDirty { + return false, fmt.Errorf("%s is equal to %s", v, c.orig) + } else if c.con.Patch() != v.Patch() && !c.patchDirty { + return true, nil + } else if c.patchDirty { + // Need to handle prereleases if present + if v.Prerelease() != "" || c.con.Prerelease() != "" { + eq := comparePrerelease(v.Prerelease(), c.con.Prerelease()) != 0 + if eq { + return true, nil + } + return false, fmt.Errorf("%s is equal to %s", v, c.orig) + } + return false, fmt.Errorf("%s is equal to %s", v, c.orig) + } + } + + eq := v.Equal(c.con) + if eq { + return false, fmt.Errorf("%s is equal to %s", v, c.orig) + } + + return true, nil +} + +func constraintGreaterThan(v *Version, c *constraint) (bool, error) { + + // If there is a pre-release on the version but the constraint isn't looking + // for them assume that pre-releases are not compatible. See issue 21 for + // more details. + if v.Prerelease() != "" && c.con.Prerelease() == "" { + return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) + } + + var eq bool + + if !c.dirty { + eq = v.Compare(c.con) == 1 + if eq { + return true, nil + } + return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig) + } + + if v.Major() > c.con.Major() { + return true, nil + } else if v.Major() < c.con.Major() { + return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig) + } else if c.minorDirty { + // This is a range case such as >11. When the version is something like + // 11.1.0 is it not > 11. For that we would need 12 or higher + return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig) + } else if c.patchDirty { + // This is for ranges such as >11.1. A version of 11.1.1 is not greater + // which one of 11.2.1 is greater + eq = v.Minor() > c.con.Minor() + if eq { + return true, nil + } + return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig) + } + + // If we have gotten here we are not comparing pre-preleases and can use the + // Compare function to accomplish that. + eq = v.Compare(c.con) == 1 + if eq { + return true, nil + } + return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig) +} + +func constraintLessThan(v *Version, c *constraint) (bool, error) { + // If there is a pre-release on the version but the constraint isn't looking + // for them assume that pre-releases are not compatible. See issue 21 for + // more details. + if v.Prerelease() != "" && c.con.Prerelease() == "" { + return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) + } + + eq := v.Compare(c.con) < 0 + if eq { + return true, nil + } + return false, fmt.Errorf("%s is greater than or equal to %s", v, c.orig) +} + +func constraintGreaterThanEqual(v *Version, c *constraint) (bool, error) { + + // If there is a pre-release on the version but the constraint isn't looking + // for them assume that pre-releases are not compatible. See issue 21 for + // more details. + if v.Prerelease() != "" && c.con.Prerelease() == "" { + return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) + } + + eq := v.Compare(c.con) >= 0 + if eq { + return true, nil + } + return false, fmt.Errorf("%s is less than %s", v, c.orig) +} + +func constraintLessThanEqual(v *Version, c *constraint) (bool, error) { + // If there is a pre-release on the version but the constraint isn't looking + // for them assume that pre-releases are not compatible. See issue 21 for + // more details. + if v.Prerelease() != "" && c.con.Prerelease() == "" { + return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) + } + + var eq bool + + if !c.dirty { + eq = v.Compare(c.con) <= 0 + if eq { + return true, nil + } + return false, fmt.Errorf("%s is greater than %s", v, c.orig) + } + + if v.Major() > c.con.Major() { + return false, fmt.Errorf("%s is greater than %s", v, c.orig) + } else if v.Major() == c.con.Major() && v.Minor() > c.con.Minor() && !c.minorDirty { + return false, fmt.Errorf("%s is greater than %s", v, c.orig) + } + + return true, nil +} + +// ~*, ~>* --> >= 0.0.0 (any) +// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0, <3.0.0 +// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0, <2.1.0 +// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0, <1.3.0 +// ~1.2.3, ~>1.2.3 --> >=1.2.3, <1.3.0 +// ~1.2.0, ~>1.2.0 --> >=1.2.0, <1.3.0 +func constraintTilde(v *Version, c *constraint) (bool, error) { + // If there is a pre-release on the version but the constraint isn't looking + // for them assume that pre-releases are not compatible. See issue 21 for + // more details. + if v.Prerelease() != "" && c.con.Prerelease() == "" { + return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) + } + + if v.LessThan(c.con) { + return false, fmt.Errorf("%s is less than %s", v, c.orig) + } + + // ~0.0.0 is a special case where all constraints are accepted. It's + // equivalent to >= 0.0.0. + if c.con.Major() == 0 && c.con.Minor() == 0 && c.con.Patch() == 0 && + !c.minorDirty && !c.patchDirty { + return true, nil + } + + if v.Major() != c.con.Major() { + return false, fmt.Errorf("%s does not have same major version as %s", v, c.orig) + } + + if v.Minor() != c.con.Minor() && !c.minorDirty { + return false, fmt.Errorf("%s does not have same major and minor version as %s", v, c.orig) + } + + return true, nil +} + +// When there is a .x (dirty) status it automatically opts in to ~. Otherwise +// it's a straight = +func constraintTildeOrEqual(v *Version, c *constraint) (bool, error) { + // If there is a pre-release on the version but the constraint isn't looking + // for them assume that pre-releases are not compatible. See issue 21 for + // more details. + if v.Prerelease() != "" && c.con.Prerelease() == "" { + return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) + } + + if c.dirty { + return constraintTilde(v, c) + } + + eq := v.Equal(c.con) + if eq { + return true, nil + } + + return false, fmt.Errorf("%s is not equal to %s", v, c.orig) +} + +// ^* --> (any) +// ^1.2.3 --> >=1.2.3 <2.0.0 +// ^1.2 --> >=1.2.0 <2.0.0 +// ^1 --> >=1.0.0 <2.0.0 +// ^0.2.3 --> >=0.2.3 <0.3.0 +// ^0.2 --> >=0.2.0 <0.3.0 +// ^0.0.3 --> >=0.0.3 <0.0.4 +// ^0.0 --> >=0.0.0 <0.1.0 +// ^0 --> >=0.0.0 <1.0.0 +func constraintCaret(v *Version, c *constraint) (bool, error) { + // If there is a pre-release on the version but the constraint isn't looking + // for them assume that pre-releases are not compatible. See issue 21 for + // more details. + if v.Prerelease() != "" && c.con.Prerelease() == "" { + return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) + } + + // This less than handles prereleases + if v.LessThan(c.con) { + return false, fmt.Errorf("%s is less than %s", v, c.orig) + } + + var eq bool + + // ^ when the major > 0 is >=x.y.z < x+1 + if c.con.Major() > 0 || c.minorDirty { + + // ^ has to be within a major range for > 0. Everything less than was + // filtered out with the LessThan call above. This filters out those + // that greater but not within the same major range. + eq = v.Major() == c.con.Major() + if eq { + return true, nil + } + return false, fmt.Errorf("%s does not have same major version as %s", v, c.orig) + } + + // ^ when the major is 0 and minor > 0 is >=0.y.z < 0.y+1 + if c.con.Major() == 0 && v.Major() > 0 { + return false, fmt.Errorf("%s does not have same major version as %s", v, c.orig) + } + // If the con Minor is > 0 it is not dirty + if c.con.Minor() > 0 || c.patchDirty { + eq = v.Minor() == c.con.Minor() + if eq { + return true, nil + } + return false, fmt.Errorf("%s does not have same minor version as %s. Expected minor versions to match when constraint major version is 0", v, c.orig) + } + // ^ when the minor is 0 and minor > 0 is =0.0.z + if c.con.Minor() == 0 && v.Minor() > 0 { + return false, fmt.Errorf("%s does not have same minor version as %s", v, c.orig) + } + + // At this point the major is 0 and the minor is 0 and not dirty. The patch + // is not dirty so we need to check if they are equal. If they are not equal + eq = c.con.Patch() == v.Patch() + if eq { + return true, nil + } + return false, fmt.Errorf("%s does not equal %s. Expect version and constraint to equal when major and minor versions are 0", v, c.orig) +} + +func isX(x string) bool { + switch x { + case "x", "*", "X": + return true + default: + return false + } +} + +func rewriteRange(i string) string { + m := constraintRangeRegex.FindAllStringSubmatch(i, -1) + if m == nil { + return i + } + o := i + for _, v := range m { + t := fmt.Sprintf(">= %s, <= %s ", v[1], v[11]) + o = strings.Replace(o, v[0], t, 1) + } + + return o +} diff --git a/go-controller/vendor/github.com/Masterminds/semver/v3/doc.go b/go-controller/vendor/github.com/Masterminds/semver/v3/doc.go new file mode 100644 index 0000000000..74f97caa57 --- /dev/null +++ b/go-controller/vendor/github.com/Masterminds/semver/v3/doc.go @@ -0,0 +1,184 @@ +/* +Package semver provides the ability to work with Semantic Versions (http://semver.org) in Go. + +Specifically it provides the ability to: + + - Parse semantic versions + - Sort semantic versions + - Check if a semantic version fits within a set of constraints + - Optionally work with a `v` prefix + +# Parsing Semantic Versions + +There are two functions that can parse semantic versions. The `StrictNewVersion` +function only parses valid version 2 semantic versions as outlined in the +specification. The `NewVersion` function attempts to coerce a version into a +semantic version and parse it. For example, if there is a leading v or a version +listed without all 3 parts (e.g. 1.2) it will attempt to coerce it into a valid +semantic version (e.g., 1.2.0). In both cases a `Version` object is returned +that can be sorted, compared, and used in constraints. + +When parsing a version an optional error can be returned if there is an issue +parsing the version. For example, + + v, err := semver.NewVersion("1.2.3-beta.1+b345") + +The version object has methods to get the parts of the version, compare it to +other versions, convert the version back into a string, and get the original +string. For more details please see the documentation +at https://godoc.org/github.com/Masterminds/semver. + +# Sorting Semantic Versions + +A set of versions can be sorted using the `sort` package from the standard library. +For example, + + raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",} + vs := make([]*semver.Version, len(raw)) + for i, r := range raw { + v, err := semver.NewVersion(r) + if err != nil { + t.Errorf("Error parsing version: %s", err) + } + + vs[i] = v + } + + sort.Sort(semver.Collection(vs)) + +# Checking Version Constraints and Comparing Versions + +There are two methods for comparing versions. One uses comparison methods on +`Version` instances and the other is using Constraints. There are some important +differences to notes between these two methods of comparison. + + 1. When two versions are compared using functions such as `Compare`, `LessThan`, + and others it will follow the specification and always include prereleases + within the comparison. It will provide an answer valid with the comparison + spec section at https://semver.org/#spec-item-11 + 2. When constraint checking is used for checks or validation it will follow a + different set of rules that are common for ranges with tools like npm/js + and Rust/Cargo. This includes considering prereleases to be invalid if the + ranges does not include on. If you want to have it include pre-releases a + simple solution is to include `-0` in your range. + 3. Constraint ranges can have some complex rules including the shorthard use of + ~ and ^. For more details on those see the options below. + +There are differences between the two methods or checking versions because the +comparison methods on `Version` follow the specification while comparison ranges +are not part of the specification. Different packages and tools have taken it +upon themselves to come up with range rules. This has resulted in differences. +For example, npm/js and Cargo/Rust follow similar patterns which PHP has a +different pattern for ^. The comparison features in this package follow the +npm/js and Cargo/Rust lead because applications using it have followed similar +patters with their versions. + +Checking a version against version constraints is one of the most featureful +parts of the package. + + c, err := semver.NewConstraint(">= 1.2.3") + if err != nil { + // Handle constraint not being parsable. + } + + v, err := semver.NewVersion("1.3") + if err != nil { + // Handle version not being parsable. + } + // Check if the version meets the constraints. The a variable will be true. + a := c.Check(v) + +# Basic Comparisons + +There are two elements to the comparisons. First, a comparison string is a list +of comma or space separated AND comparisons. These are then separated by || (OR) +comparisons. For example, `">= 1.2 < 3.0.0 || >= 4.2.3"` is looking for a +comparison that's greater than or equal to 1.2 and less than 3.0.0 or is +greater than or equal to 4.2.3. This can also be written as +`">= 1.2, < 3.0.0 || >= 4.2.3"` + +The basic comparisons are: + + - `=`: equal (aliased to no operator) + - `!=`: not equal + - `>`: greater than + - `<`: less than + - `>=`: greater than or equal to + - `<=`: less than or equal to + +# Hyphen Range Comparisons + +There are multiple methods to handle ranges and the first is hyphens ranges. +These look like: + + - `1.2 - 1.4.5` which is equivalent to `>= 1.2, <= 1.4.5` + - `2.3.4 - 4.5` which is equivalent to `>= 2.3.4 <= 4.5` + +# Wildcards In Comparisons + +The `x`, `X`, and `*` characters can be used as a wildcard character. This works +for all comparison operators. When used on the `=` operator it falls +back to the tilde operation. For example, + + - `1.2.x` is equivalent to `>= 1.2.0 < 1.3.0` + - `>= 1.2.x` is equivalent to `>= 1.2.0` + - `<= 2.x` is equivalent to `<= 3` + - `*` is equivalent to `>= 0.0.0` + +Tilde Range Comparisons (Patch) + +The tilde (`~`) comparison operator is for patch level ranges when a minor +version is specified and major level changes when the minor number is missing. +For example, + + - `~1.2.3` is equivalent to `>= 1.2.3 < 1.3.0` + - `~1` is equivalent to `>= 1, < 2` + - `~2.3` is equivalent to `>= 2.3 < 2.4` + - `~1.2.x` is equivalent to `>= 1.2.0 < 1.3.0` + - `~1.x` is equivalent to `>= 1 < 2` + +Caret Range Comparisons (Major) + +The caret (`^`) comparison operator is for major level changes once a stable +(1.0.0) release has occurred. Prior to a 1.0.0 release the minor versions acts +as the API stability level. This is useful when comparisons of API versions as a +major change is API breaking. For example, + + - `^1.2.3` is equivalent to `>= 1.2.3, < 2.0.0` + - `^1.2.x` is equivalent to `>= 1.2.0, < 2.0.0` + - `^2.3` is equivalent to `>= 2.3, < 3` + - `^2.x` is equivalent to `>= 2.0.0, < 3` + - `^0.2.3` is equivalent to `>=0.2.3 <0.3.0` + - `^0.2` is equivalent to `>=0.2.0 <0.3.0` + - `^0.0.3` is equivalent to `>=0.0.3 <0.0.4` + - `^0.0` is equivalent to `>=0.0.0 <0.1.0` + - `^0` is equivalent to `>=0.0.0 <1.0.0` + +# Validation + +In addition to testing a version against a constraint, a version can be validated +against a constraint. When validation fails a slice of errors containing why a +version didn't meet the constraint is returned. For example, + + c, err := semver.NewConstraint("<= 1.2.3, >= 1.4") + if err != nil { + // Handle constraint not being parseable. + } + + v, _ := semver.NewVersion("1.3") + if err != nil { + // Handle version not being parseable. + } + + // Validate a version against a constraint. + a, msgs := c.Validate(v) + // a is false + for _, m := range msgs { + fmt.Println(m) + + // Loops over the errors which would read + // "1.3 is greater than 1.2.3" + // "1.3 is less than 1.4" + } +*/ +package semver diff --git a/go-controller/vendor/github.com/Masterminds/semver/v3/version.go b/go-controller/vendor/github.com/Masterminds/semver/v3/version.go new file mode 100644 index 0000000000..7c4bed3347 --- /dev/null +++ b/go-controller/vendor/github.com/Masterminds/semver/v3/version.go @@ -0,0 +1,639 @@ +package semver + +import ( + "bytes" + "database/sql/driver" + "encoding/json" + "errors" + "fmt" + "regexp" + "strconv" + "strings" +) + +// The compiled version of the regex created at init() is cached here so it +// only needs to be created once. +var versionRegex *regexp.Regexp + +var ( + // ErrInvalidSemVer is returned a version is found to be invalid when + // being parsed. + ErrInvalidSemVer = errors.New("Invalid Semantic Version") + + // ErrEmptyString is returned when an empty string is passed in for parsing. + ErrEmptyString = errors.New("Version string empty") + + // ErrInvalidCharacters is returned when invalid characters are found as + // part of a version + ErrInvalidCharacters = errors.New("Invalid characters in version") + + // ErrSegmentStartsZero is returned when a version segment starts with 0. + // This is invalid in SemVer. + ErrSegmentStartsZero = errors.New("Version segment starts with 0") + + // ErrInvalidMetadata is returned when the metadata is an invalid format + ErrInvalidMetadata = errors.New("Invalid Metadata string") + + // ErrInvalidPrerelease is returned when the pre-release is an invalid format + ErrInvalidPrerelease = errors.New("Invalid Prerelease string") +) + +// semVerRegex is the regular expression used to parse a semantic version. +const semVerRegex string = `v?([0-9]+)(\.[0-9]+)?(\.[0-9]+)?` + + `(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` + + `(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` + +// Version represents a single semantic version. +type Version struct { + major, minor, patch uint64 + pre string + metadata string + original string +} + +func init() { + versionRegex = regexp.MustCompile("^" + semVerRegex + "$") +} + +const ( + num string = "0123456789" + allowed string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-" + num +) + +// StrictNewVersion parses a given version and returns an instance of Version or +// an error if unable to parse the version. Only parses valid semantic versions. +// Performs checking that can find errors within the version. +// If you want to coerce a version such as 1 or 1.2 and parse it as the 1.x +// releases of semver did, use the NewVersion() function. +func StrictNewVersion(v string) (*Version, error) { + // Parsing here does not use RegEx in order to increase performance and reduce + // allocations. + + if len(v) == 0 { + return nil, ErrEmptyString + } + + // Split the parts into [0]major, [1]minor, and [2]patch,prerelease,build + parts := strings.SplitN(v, ".", 3) + if len(parts) != 3 { + return nil, ErrInvalidSemVer + } + + sv := &Version{ + original: v, + } + + // check for prerelease or build metadata + var extra []string + if strings.ContainsAny(parts[2], "-+") { + // Start with the build metadata first as it needs to be on the right + extra = strings.SplitN(parts[2], "+", 2) + if len(extra) > 1 { + // build metadata found + sv.metadata = extra[1] + parts[2] = extra[0] + } + + extra = strings.SplitN(parts[2], "-", 2) + if len(extra) > 1 { + // prerelease found + sv.pre = extra[1] + parts[2] = extra[0] + } + } + + // Validate the number segments are valid. This includes only having positive + // numbers and no leading 0's. + for _, p := range parts { + if !containsOnly(p, num) { + return nil, ErrInvalidCharacters + } + + if len(p) > 1 && p[0] == '0' { + return nil, ErrSegmentStartsZero + } + } + + // Extract the major, minor, and patch elements onto the returned Version + var err error + sv.major, err = strconv.ParseUint(parts[0], 10, 64) + if err != nil { + return nil, err + } + + sv.minor, err = strconv.ParseUint(parts[1], 10, 64) + if err != nil { + return nil, err + } + + sv.patch, err = strconv.ParseUint(parts[2], 10, 64) + if err != nil { + return nil, err + } + + // No prerelease or build metadata found so returning now as a fastpath. + if sv.pre == "" && sv.metadata == "" { + return sv, nil + } + + if sv.pre != "" { + if err = validatePrerelease(sv.pre); err != nil { + return nil, err + } + } + + if sv.metadata != "" { + if err = validateMetadata(sv.metadata); err != nil { + return nil, err + } + } + + return sv, nil +} + +// NewVersion parses a given version and returns an instance of Version or +// an error if unable to parse the version. If the version is SemVer-ish it +// attempts to convert it to SemVer. If you want to validate it was a strict +// semantic version at parse time see StrictNewVersion(). +func NewVersion(v string) (*Version, error) { + m := versionRegex.FindStringSubmatch(v) + if m == nil { + return nil, ErrInvalidSemVer + } + + sv := &Version{ + metadata: m[8], + pre: m[5], + original: v, + } + + var err error + sv.major, err = strconv.ParseUint(m[1], 10, 64) + if err != nil { + return nil, fmt.Errorf("Error parsing version segment: %s", err) + } + + if m[2] != "" { + sv.minor, err = strconv.ParseUint(strings.TrimPrefix(m[2], "."), 10, 64) + if err != nil { + return nil, fmt.Errorf("Error parsing version segment: %s", err) + } + } else { + sv.minor = 0 + } + + if m[3] != "" { + sv.patch, err = strconv.ParseUint(strings.TrimPrefix(m[3], "."), 10, 64) + if err != nil { + return nil, fmt.Errorf("Error parsing version segment: %s", err) + } + } else { + sv.patch = 0 + } + + // Perform some basic due diligence on the extra parts to ensure they are + // valid. + + if sv.pre != "" { + if err = validatePrerelease(sv.pre); err != nil { + return nil, err + } + } + + if sv.metadata != "" { + if err = validateMetadata(sv.metadata); err != nil { + return nil, err + } + } + + return sv, nil +} + +// New creates a new instance of Version with each of the parts passed in as +// arguments instead of parsing a version string. +func New(major, minor, patch uint64, pre, metadata string) *Version { + v := Version{ + major: major, + minor: minor, + patch: patch, + pre: pre, + metadata: metadata, + original: "", + } + + v.original = v.String() + + return &v +} + +// MustParse parses a given version and panics on error. +func MustParse(v string) *Version { + sv, err := NewVersion(v) + if err != nil { + panic(err) + } + return sv +} + +// String converts a Version object to a string. +// Note, if the original version contained a leading v this version will not. +// See the Original() method to retrieve the original value. Semantic Versions +// don't contain a leading v per the spec. Instead it's optional on +// implementation. +func (v Version) String() string { + var buf bytes.Buffer + + fmt.Fprintf(&buf, "%d.%d.%d", v.major, v.minor, v.patch) + if v.pre != "" { + fmt.Fprintf(&buf, "-%s", v.pre) + } + if v.metadata != "" { + fmt.Fprintf(&buf, "+%s", v.metadata) + } + + return buf.String() +} + +// Original returns the original value passed in to be parsed. +func (v *Version) Original() string { + return v.original +} + +// Major returns the major version. +func (v Version) Major() uint64 { + return v.major +} + +// Minor returns the minor version. +func (v Version) Minor() uint64 { + return v.minor +} + +// Patch returns the patch version. +func (v Version) Patch() uint64 { + return v.patch +} + +// Prerelease returns the pre-release version. +func (v Version) Prerelease() string { + return v.pre +} + +// Metadata returns the metadata on the version. +func (v Version) Metadata() string { + return v.metadata +} + +// originalVPrefix returns the original 'v' prefix if any. +func (v Version) originalVPrefix() string { + // Note, only lowercase v is supported as a prefix by the parser. + if v.original != "" && v.original[:1] == "v" { + return v.original[:1] + } + return "" +} + +// IncPatch produces the next patch version. +// If the current version does not have prerelease/metadata information, +// it unsets metadata and prerelease values, increments patch number. +// If the current version has any of prerelease or metadata information, +// it unsets both values and keeps current patch value +func (v Version) IncPatch() Version { + vNext := v + // according to http://semver.org/#spec-item-9 + // Pre-release versions have a lower precedence than the associated normal version. + // according to http://semver.org/#spec-item-10 + // Build metadata SHOULD be ignored when determining version precedence. + if v.pre != "" { + vNext.metadata = "" + vNext.pre = "" + } else { + vNext.metadata = "" + vNext.pre = "" + vNext.patch = v.patch + 1 + } + vNext.original = v.originalVPrefix() + "" + vNext.String() + return vNext +} + +// IncMinor produces the next minor version. +// Sets patch to 0. +// Increments minor number. +// Unsets metadata. +// Unsets prerelease status. +func (v Version) IncMinor() Version { + vNext := v + vNext.metadata = "" + vNext.pre = "" + vNext.patch = 0 + vNext.minor = v.minor + 1 + vNext.original = v.originalVPrefix() + "" + vNext.String() + return vNext +} + +// IncMajor produces the next major version. +// Sets patch to 0. +// Sets minor to 0. +// Increments major number. +// Unsets metadata. +// Unsets prerelease status. +func (v Version) IncMajor() Version { + vNext := v + vNext.metadata = "" + vNext.pre = "" + vNext.patch = 0 + vNext.minor = 0 + vNext.major = v.major + 1 + vNext.original = v.originalVPrefix() + "" + vNext.String() + return vNext +} + +// SetPrerelease defines the prerelease value. +// Value must not include the required 'hyphen' prefix. +func (v Version) SetPrerelease(prerelease string) (Version, error) { + vNext := v + if len(prerelease) > 0 { + if err := validatePrerelease(prerelease); err != nil { + return vNext, err + } + } + vNext.pre = prerelease + vNext.original = v.originalVPrefix() + "" + vNext.String() + return vNext, nil +} + +// SetMetadata defines metadata value. +// Value must not include the required 'plus' prefix. +func (v Version) SetMetadata(metadata string) (Version, error) { + vNext := v + if len(metadata) > 0 { + if err := validateMetadata(metadata); err != nil { + return vNext, err + } + } + vNext.metadata = metadata + vNext.original = v.originalVPrefix() + "" + vNext.String() + return vNext, nil +} + +// LessThan tests if one version is less than another one. +func (v *Version) LessThan(o *Version) bool { + return v.Compare(o) < 0 +} + +// GreaterThan tests if one version is greater than another one. +func (v *Version) GreaterThan(o *Version) bool { + return v.Compare(o) > 0 +} + +// Equal tests if two versions are equal to each other. +// Note, versions can be equal with different metadata since metadata +// is not considered part of the comparable version. +func (v *Version) Equal(o *Version) bool { + return v.Compare(o) == 0 +} + +// Compare compares this version to another one. It returns -1, 0, or 1 if +// the version smaller, equal, or larger than the other version. +// +// Versions are compared by X.Y.Z. Build metadata is ignored. Prerelease is +// lower than the version without a prerelease. Compare always takes into account +// prereleases. If you want to work with ranges using typical range syntaxes that +// skip prereleases if the range is not looking for them use constraints. +func (v *Version) Compare(o *Version) int { + // Compare the major, minor, and patch version for differences. If a + // difference is found return the comparison. + if d := compareSegment(v.Major(), o.Major()); d != 0 { + return d + } + if d := compareSegment(v.Minor(), o.Minor()); d != 0 { + return d + } + if d := compareSegment(v.Patch(), o.Patch()); d != 0 { + return d + } + + // At this point the major, minor, and patch versions are the same. + ps := v.pre + po := o.Prerelease() + + if ps == "" && po == "" { + return 0 + } + if ps == "" { + return 1 + } + if po == "" { + return -1 + } + + return comparePrerelease(ps, po) +} + +// UnmarshalJSON implements JSON.Unmarshaler interface. +func (v *Version) UnmarshalJSON(b []byte) error { + var s string + if err := json.Unmarshal(b, &s); err != nil { + return err + } + temp, err := NewVersion(s) + if err != nil { + return err + } + v.major = temp.major + v.minor = temp.minor + v.patch = temp.patch + v.pre = temp.pre + v.metadata = temp.metadata + v.original = temp.original + return nil +} + +// MarshalJSON implements JSON.Marshaler interface. +func (v Version) MarshalJSON() ([]byte, error) { + return json.Marshal(v.String()) +} + +// UnmarshalText implements the encoding.TextUnmarshaler interface. +func (v *Version) UnmarshalText(text []byte) error { + temp, err := NewVersion(string(text)) + if err != nil { + return err + } + + *v = *temp + + return nil +} + +// MarshalText implements the encoding.TextMarshaler interface. +func (v Version) MarshalText() ([]byte, error) { + return []byte(v.String()), nil +} + +// Scan implements the SQL.Scanner interface. +func (v *Version) Scan(value interface{}) error { + var s string + s, _ = value.(string) + temp, err := NewVersion(s) + if err != nil { + return err + } + v.major = temp.major + v.minor = temp.minor + v.patch = temp.patch + v.pre = temp.pre + v.metadata = temp.metadata + v.original = temp.original + return nil +} + +// Value implements the Driver.Valuer interface. +func (v Version) Value() (driver.Value, error) { + return v.String(), nil +} + +func compareSegment(v, o uint64) int { + if v < o { + return -1 + } + if v > o { + return 1 + } + + return 0 +} + +func comparePrerelease(v, o string) int { + // split the prelease versions by their part. The separator, per the spec, + // is a . + sparts := strings.Split(v, ".") + oparts := strings.Split(o, ".") + + // Find the longer length of the parts to know how many loop iterations to + // go through. + slen := len(sparts) + olen := len(oparts) + + l := slen + if olen > slen { + l = olen + } + + // Iterate over each part of the prereleases to compare the differences. + for i := 0; i < l; i++ { + // Since the lentgh of the parts can be different we need to create + // a placeholder. This is to avoid out of bounds issues. + stemp := "" + if i < slen { + stemp = sparts[i] + } + + otemp := "" + if i < olen { + otemp = oparts[i] + } + + d := comparePrePart(stemp, otemp) + if d != 0 { + return d + } + } + + // Reaching here means two versions are of equal value but have different + // metadata (the part following a +). They are not identical in string form + // but the version comparison finds them to be equal. + return 0 +} + +func comparePrePart(s, o string) int { + // Fastpath if they are equal + if s == o { + return 0 + } + + // When s or o are empty we can use the other in an attempt to determine + // the response. + if s == "" { + if o != "" { + return -1 + } + return 1 + } + + if o == "" { + if s != "" { + return 1 + } + return -1 + } + + // When comparing strings "99" is greater than "103". To handle + // cases like this we need to detect numbers and compare them. According + // to the semver spec, numbers are always positive. If there is a - at the + // start like -99 this is to be evaluated as an alphanum. numbers always + // have precedence over alphanum. Parsing as Uints because negative numbers + // are ignored. + + oi, n1 := strconv.ParseUint(o, 10, 64) + si, n2 := strconv.ParseUint(s, 10, 64) + + // The case where both are strings compare the strings + if n1 != nil && n2 != nil { + if s > o { + return 1 + } + return -1 + } else if n1 != nil { + // o is a string and s is a number + return -1 + } else if n2 != nil { + // s is a string and o is a number + return 1 + } + // Both are numbers + if si > oi { + return 1 + } + return -1 +} + +// Like strings.ContainsAny but does an only instead of any. +func containsOnly(s string, comp string) bool { + return strings.IndexFunc(s, func(r rune) bool { + return !strings.ContainsRune(comp, r) + }) == -1 +} + +// From the spec, "Identifiers MUST comprise only +// ASCII alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty. +// Numeric identifiers MUST NOT include leading zeroes.". These segments can +// be dot separated. +func validatePrerelease(p string) error { + eparts := strings.Split(p, ".") + for _, p := range eparts { + if containsOnly(p, num) { + if len(p) > 1 && p[0] == '0' { + return ErrSegmentStartsZero + } + } else if !containsOnly(p, allowed) { + return ErrInvalidPrerelease + } + } + + return nil +} + +// From the spec, "Build metadata MAY be denoted by +// appending a plus sign and a series of dot separated identifiers immediately +// following the patch or pre-release version. Identifiers MUST comprise only +// ASCII alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty." +func validateMetadata(m string) error { + eparts := strings.Split(m, ".") + for _, p := range eparts { + if !containsOnly(p, allowed) { + return ErrInvalidMetadata + } + } + return nil +} diff --git a/go-controller/vendor/github.com/containernetworking/cni/libcni/api.go b/go-controller/vendor/github.com/containernetworking/cni/libcni/api.go index 0d82a2dd3c..5c7f3b028c 100644 --- a/go-controller/vendor/github.com/containernetworking/cni/libcni/api.go +++ b/go-controller/vendor/github.com/containernetworking/cni/libcni/api.go @@ -15,7 +15,7 @@ package libcni // Note this is the actual implementation of the CNI specification, which -// is reflected in the https://github.com/containernetworking/cni/blob/master/SPEC.md file +// is reflected in the SPEC.md file. // it is typically bundled into runtime providers (i.e. containerd or cri-o would use this // before calling runc or hcsshim). It is also bundled into CNI providers as well, for example, // to add an IP to a container, to parse the configuration of the CNI and so on. @@ -24,9 +24,9 @@ import ( "context" "encoding/json" "fmt" - "io/ioutil" "os" "path/filepath" + "sort" "strings" "github.com/containernetworking/cni/pkg/invoke" @@ -38,6 +38,8 @@ import ( var ( CacheDir = "/var/lib/cni" + // slightly awkward wording to preserve anyone matching on error strings + ErrorCheckNotSupp = fmt.Errorf("does not support the CHECK command") ) const ( @@ -77,6 +79,20 @@ type NetworkConfigList struct { Bytes []byte } +type NetworkAttachment struct { + ContainerID string + Network string + IfName string + Config []byte + NetNS string + CniArgs [][2]string + CapabilityArgs map[string]interface{} +} + +type GCArgs struct { + ValidAttachments []types.GCAttachment +} + type CNI interface { AddNetworkList(ctx context.Context, net *NetworkConfigList, rt *RuntimeConf) (types.Result, error) CheckNetworkList(ctx context.Context, net *NetworkConfigList, rt *RuntimeConf) error @@ -92,6 +108,11 @@ type CNI interface { ValidateNetworkList(ctx context.Context, net *NetworkConfigList) ([]string, error) ValidateNetwork(ctx context.Context, net *NetworkConfig) ([]string, error) + + GCNetworkList(ctx context.Context, net *NetworkConfigList, args *GCArgs) error + GetStatusNetworkList(ctx context.Context, net *NetworkConfigList) error + + GetCachedAttachments(containerID string) ([]*NetworkAttachment, error) } type CNIConfig struct { @@ -139,8 +160,11 @@ func buildOneConfig(name, cniVersion string, orig *NetworkConfig, prevResult typ if err != nil { return nil, err } + if rt != nil { + return injectRuntimeConfig(orig, rt) + } - return injectRuntimeConfig(orig, rt) + return orig, nil } // This function takes a libcni RuntimeConf structure and injects values into @@ -195,6 +219,7 @@ type cachedInfo struct { Config []byte `json:"config"` IfName string `json:"ifName"` NetworkName string `json:"networkName"` + NetNS string `json:"netns,omitempty"` CniArgs [][2]string `json:"cniArgs,omitempty"` CapabilityArgs map[string]interface{} `json:"capabilityArgs,omitempty"` RawResult map[string]interface{} `json:"result,omitempty"` @@ -229,6 +254,7 @@ func (c *CNIConfig) cacheAdd(result types.Result, config []byte, netName string, Config: config, IfName: rt.IfName, NetworkName: netName, + NetNS: rt.NetNS, CniArgs: rt.Args, CapabilityArgs: rt.CapabilityArgs, } @@ -254,11 +280,11 @@ func (c *CNIConfig) cacheAdd(result types.Result, config []byte, netName string, if err != nil { return err } - if err := os.MkdirAll(filepath.Dir(fname), 0700); err != nil { + if err := os.MkdirAll(filepath.Dir(fname), 0o700); err != nil { return err } - return ioutil.WriteFile(fname, newBytes, 0600) + return os.WriteFile(fname, newBytes, 0o600) } func (c *CNIConfig) cacheDel(netName string, rt *RuntimeConf) error { @@ -277,7 +303,7 @@ func (c *CNIConfig) getCachedConfig(netName string, rt *RuntimeConf) ([]byte, *R if err != nil { return nil, nil, err } - bytes, err = ioutil.ReadFile(fname) + bytes, err = os.ReadFile(fname) if err != nil { // Ignore read errors; the cached result may not exist on-disk return nil, nil, nil @@ -305,7 +331,7 @@ func (c *CNIConfig) getLegacyCachedResult(netName, cniVersion string, rt *Runtim if err != nil { return nil, err } - data, err := ioutil.ReadFile(fname) + data, err := os.ReadFile(fname) if err != nil { // Ignore read errors; the cached result may not exist on-disk return nil, nil @@ -333,7 +359,7 @@ func (c *CNIConfig) getCachedResult(netName, cniVersion string, rt *RuntimeConf) if err != nil { return nil, err } - fdata, err := ioutil.ReadFile(fname) + fdata, err := os.ReadFile(fname) if err != nil { // Ignore read errors; the cached result may not exist on-disk return nil, nil @@ -390,6 +416,65 @@ func (c *CNIConfig) GetNetworkCachedConfig(net *NetworkConfig, rt *RuntimeConf) return c.getCachedConfig(net.Network.Name, rt) } +// GetCachedAttachments returns a list of network attachments from the cache. +// The returned list will be filtered by the containerID if the value is not empty. +func (c *CNIConfig) GetCachedAttachments(containerID string) ([]*NetworkAttachment, error) { + dirPath := filepath.Join(c.getCacheDir(&RuntimeConf{}), "results") + entries, err := os.ReadDir(dirPath) + if err != nil { + return nil, err + } + + fileNames := make([]string, 0, len(entries)) + for _, e := range entries { + fileNames = append(fileNames, e.Name()) + } + sort.Strings(fileNames) + + attachments := []*NetworkAttachment{} + for _, fname := range fileNames { + if len(containerID) > 0 { + part := fmt.Sprintf("-%s-", containerID) + pos := strings.Index(fname, part) + if pos <= 0 || pos+len(part) >= len(fname) { + continue + } + } + + cacheFile := filepath.Join(dirPath, fname) + bytes, err := os.ReadFile(cacheFile) + if err != nil { + continue + } + + cachedInfo := cachedInfo{} + + if err := json.Unmarshal(bytes, &cachedInfo); err != nil { + continue + } + if cachedInfo.Kind != CNICacheV1 { + continue + } + if len(containerID) > 0 && cachedInfo.ContainerID != containerID { + continue + } + if cachedInfo.IfName == "" || cachedInfo.NetworkName == "" { + continue + } + + attachments = append(attachments, &NetworkAttachment{ + ContainerID: cachedInfo.ContainerID, + Network: cachedInfo.NetworkName, + IfName: cachedInfo.IfName, + Config: cachedInfo.Config, + NetNS: cachedInfo.NetNS, + CniArgs: cachedInfo.CniArgs, + CapabilityArgs: cachedInfo.CapabilityArgs, + }) + } + return attachments, nil +} + func (c *CNIConfig) addNetwork(ctx context.Context, name, cniVersion string, net *NetworkConfig, prevResult types.Result, rt *RuntimeConf) (types.Result, error) { c.ensureExec() pluginPath, err := c.exec.FindInPath(net.Network.Type, c.Path) @@ -453,7 +538,7 @@ func (c *CNIConfig) CheckNetworkList(ctx context.Context, list *NetworkConfigLis if gtet, err := version.GreaterThanOrEqualTo(list.CNIVersion, "0.4.0"); err != nil { return err } else if !gtet { - return fmt.Errorf("configuration version %q does not support the CHECK command", list.CNIVersion) + return fmt.Errorf("configuration version %q %w", list.CNIVersion, ErrorCheckNotSupp) } if list.DisableCheck { @@ -497,9 +582,9 @@ func (c *CNIConfig) DelNetworkList(ctx context.Context, list *NetworkConfigList, if gtet, err := version.GreaterThanOrEqualTo(list.CNIVersion, "0.4.0"); err != nil { return err } else if gtet { - cachedResult, err = c.getCachedResult(list.Name, list.CNIVersion, rt) - if err != nil { - return fmt.Errorf("failed to get network %q cached result: %w", list.Name, err) + if cachedResult, err = c.getCachedResult(list.Name, list.CNIVersion, rt); err != nil { + _ = c.cacheDel(list.Name, rt) + cachedResult = nil } } @@ -509,7 +594,10 @@ func (c *CNIConfig) DelNetworkList(ctx context.Context, list *NetworkConfigList, return fmt.Errorf("plugin %s failed (delete): %w", pluginDescription(net.Network), err) } } - _ = c.cacheDel(list.Name, rt) + + if cachedResult != nil { + _ = c.cacheDel(list.Name, rt) + } return nil } @@ -547,7 +635,7 @@ func (c *CNIConfig) CheckNetwork(ctx context.Context, net *NetworkConfig, rt *Ru if gtet, err := version.GreaterThanOrEqualTo(net.Network.CNIVersion, "0.4.0"); err != nil { return err } else if !gtet { - return fmt.Errorf("configuration version %q does not support the CHECK command", net.Network.CNIVersion) + return fmt.Errorf("configuration version %q %w", net.Network.CNIVersion, ErrorCheckNotSupp) } cachedResult, err := c.getCachedResult(net.Network.Name, net.Network.CNIVersion, rt) @@ -666,6 +754,116 @@ func (c *CNIConfig) GetVersionInfo(ctx context.Context, pluginType string) (vers return invoke.GetVersionInfo(ctx, pluginPath, c.exec) } +// GCNetworkList will do two things +// - dump the list of cached attachments, and issue deletes as necessary +// - issue a GC to the underlying plugins (if the version is high enough) +func (c *CNIConfig) GCNetworkList(ctx context.Context, list *NetworkConfigList, args *GCArgs) error { + // First, get the list of cached attachments + cachedAttachments, err := c.GetCachedAttachments("") + if err != nil { + return nil + } + + validAttachments := make(map[types.GCAttachment]interface{}, len(args.ValidAttachments)) + for _, a := range args.ValidAttachments { + validAttachments[a] = nil + } + + var errs []error + + for _, cachedAttachment := range cachedAttachments { + if cachedAttachment.Network != list.Name { + continue + } + // we found this attachment + gca := types.GCAttachment{ + ContainerID: cachedAttachment.ContainerID, + IfName: cachedAttachment.IfName, + } + if _, ok := validAttachments[gca]; ok { + continue + } + // otherwise, this attachment wasn't valid and we should issue a CNI DEL + rt := RuntimeConf{ + ContainerID: cachedAttachment.ContainerID, + NetNS: cachedAttachment.NetNS, + IfName: cachedAttachment.IfName, + Args: cachedAttachment.CniArgs, + CapabilityArgs: cachedAttachment.CapabilityArgs, + } + if err := c.DelNetworkList(ctx, list, &rt); err != nil { + errs = append(errs, fmt.Errorf("failed to delete stale attachment %s %s: %w", rt.ContainerID, rt.IfName, err)) + } + } + + // now, if the version supports it, issue a GC + if gt, _ := version.GreaterThanOrEqualTo(list.CNIVersion, "1.1.0"); gt { + inject := map[string]interface{}{ + "name": list.Name, + "cniVersion": list.CNIVersion, + "cni.dev/valid-attachments": args.ValidAttachments, + } + for _, plugin := range list.Plugins { + // build config here + pluginConfig, err := InjectConf(plugin, inject) + if err != nil { + errs = append(errs, fmt.Errorf("failed to generate configuration to GC plugin %s: %w", plugin.Network.Type, err)) + } + if err := c.gcNetwork(ctx, pluginConfig); err != nil { + errs = append(errs, fmt.Errorf("failed to GC plugin %s: %w", plugin.Network.Type, err)) + } + } + } + + return joinErrors(errs...) +} + +func (c *CNIConfig) gcNetwork(ctx context.Context, net *NetworkConfig) error { + c.ensureExec() + pluginPath, err := c.exec.FindInPath(net.Network.Type, c.Path) + if err != nil { + return err + } + args := c.args("GC", &RuntimeConf{}) + + return invoke.ExecPluginWithoutResult(ctx, pluginPath, net.Bytes, args, c.exec) +} + +func (c *CNIConfig) GetStatusNetworkList(ctx context.Context, list *NetworkConfigList) error { + // If the version doesn't support status, abort. + if gt, _ := version.GreaterThanOrEqualTo(list.CNIVersion, "1.1.0"); !gt { + return nil + } + + inject := map[string]interface{}{ + "name": list.Name, + "cniVersion": list.CNIVersion, + } + + for _, plugin := range list.Plugins { + // build config here + pluginConfig, err := InjectConf(plugin, inject) + if err != nil { + return fmt.Errorf("failed to generate configuration to get plugin STATUS %s: %w", plugin.Network.Type, err) + } + if err := c.getStatusNetwork(ctx, pluginConfig); err != nil { + return err // Don't collect errors here, so we return a clean error code. + } + } + return nil +} + +func (c *CNIConfig) getStatusNetwork(ctx context.Context, net *NetworkConfig) error { + c.ensureExec() + pluginPath, err := c.exec.FindInPath(net.Network.Type, c.Path) + if err != nil { + return err + } + args := c.args("STATUS", &RuntimeConf{}) + + return invoke.ExecPluginWithoutResult(ctx, pluginPath, net.Bytes, args, c.exec) +} + // ===== func (c *CNIConfig) args(action string, rt *RuntimeConf) *invoke.Args { return &invoke.Args{ diff --git a/go-controller/vendor/github.com/containernetworking/cni/libcni/conf.go b/go-controller/vendor/github.com/containernetworking/cni/libcni/conf.go index 3cd6a59d1c..6c5d99de98 100644 --- a/go-controller/vendor/github.com/containernetworking/cni/libcni/conf.go +++ b/go-controller/vendor/github.com/containernetworking/cni/libcni/conf.go @@ -16,13 +16,17 @@ package libcni import ( "encoding/json" + "errors" "fmt" - "io/ioutil" "os" "path/filepath" "sort" + "strings" + + "github.com/Masterminds/semver/v3" "github.com/containernetworking/cni/pkg/types" + "github.com/containernetworking/cni/pkg/version" ) type NotFoundError struct { @@ -54,7 +58,7 @@ func ConfFromBytes(bytes []byte) (*NetworkConfig, error) { } func ConfFromFile(filename string) (*NetworkConfig, error) { - bytes, err := ioutil.ReadFile(filename) + bytes, err := os.ReadFile(filename) if err != nil { return nil, fmt.Errorf("error reading %s: %w", filename, err) } @@ -85,11 +89,63 @@ func ConfListFromBytes(bytes []byte) (*NetworkConfigList, error) { } } + rawVersions, ok := rawList["cniVersions"] + if ok { + // Parse the current package CNI version + currentVersion, err := semver.NewVersion(version.Current()) + if err != nil { + panic("CNI version is invalid semver!") + } + + rvs, ok := rawVersions.([]interface{}) + if !ok { + return nil, fmt.Errorf("error parsing configuration list: invalid type for cniVersions: %T", rvs) + } + vs := make([]*semver.Version, 0, len(rvs)) + for i, rv := range rvs { + v, ok := rv.(string) + if !ok { + return nil, fmt.Errorf("error parsing configuration list: invalid type for cniVersions index %d: %T", i, rv) + } + if v, err := semver.NewVersion(v); err != nil { + return nil, fmt.Errorf("error parsing configuration list: invalid cniVersions entry %s at index %d: %w", v, i, err) + } else if !v.GreaterThan(currentVersion) { + // Skip versions "greater" than this implementation of the spec + vs = append(vs, v) + } + } + + // if cniVersion was already set, append it to the list for sorting. + if cniVersion != "" { + if v, err := semver.NewVersion(cniVersion); err != nil { + return nil, fmt.Errorf("error parsing configuration list: invalid cniVersion %s: %w", cniVersion, err) + } else if !v.GreaterThan(currentVersion) { + // ignore any versions higher than the current implemented spec version + vs = append(vs, v) + } + } + sort.Sort(semver.Collection(vs)) + if len(vs) > 0 { + cniVersion = vs[len(vs)-1].String() + } + } + disableCheck := false if rawDisableCheck, ok := rawList["disableCheck"]; ok { disableCheck, ok = rawDisableCheck.(bool) if !ok { - return nil, fmt.Errorf("error parsing configuration list: invalid disableCheck type %T", rawDisableCheck) + disableCheckStr, ok := rawDisableCheck.(string) + if !ok { + return nil, fmt.Errorf("error parsing configuration list: invalid disableCheck type %T", rawDisableCheck) + } + switch { + case strings.ToLower(disableCheckStr) == "false": + disableCheck = false + case strings.ToLower(disableCheckStr) == "true": + disableCheck = true + default: + return nil, fmt.Errorf("error parsing configuration list: invalid disableCheck value %q", disableCheckStr) + } } } @@ -129,7 +185,7 @@ func ConfListFromBytes(bytes []byte) (*NetworkConfigList, error) { } func ConfListFromFile(filename string) (*NetworkConfigList, error) { - bytes, err := ioutil.ReadFile(filename) + bytes, err := os.ReadFile(filename) if err != nil { return nil, fmt.Errorf("error reading %s: %w", filename, err) } @@ -138,7 +194,7 @@ func ConfListFromFile(filename string) (*NetworkConfigList, error) { func ConfFiles(dir string, extensions []string) ([]string, error) { // In part, adapted from rkt/networking/podenv.go#listFiles - files, err := ioutil.ReadDir(dir) + files, err := os.ReadDir(dir) switch { case err == nil: // break case os.IsNotExist(err): @@ -206,7 +262,8 @@ func LoadConfList(dir, name string) (*NetworkConfigList, error) { singleConf, err := LoadConf(dir, name) if err != nil { // A little extra logic so the error makes sense - if _, ok := err.(NoConfigsFoundError); len(files) != 0 && ok { + var ncfErr NoConfigsFoundError + if len(files) != 0 && errors.As(err, &ncfErr) { // Config lists found but no config files found return nil, NotFoundError{dir, name} } diff --git a/go-controller/vendor/github.com/containernetworking/cni/libcni/multierror.go b/go-controller/vendor/github.com/containernetworking/cni/libcni/multierror.go new file mode 100644 index 0000000000..100fb8392d --- /dev/null +++ b/go-controller/vendor/github.com/containernetworking/cni/libcni/multierror.go @@ -0,0 +1,58 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Copyright the CNI authors +// +// 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. +// +// Adapted from errors/join.go from go 1.20 +// This package can be removed once the toolchain is updated to 1.20 + +package libcni + +func joinErrors(errs ...error) error { + n := 0 + for _, err := range errs { + if err != nil { + n++ + } + } + if n == 0 { + return nil + } + e := &multiError{ + errs: make([]error, 0, n), + } + for _, err := range errs { + if err != nil { + e.errs = append(e.errs, err) + } + } + return e +} + +type multiError struct { + errs []error +} + +func (e *multiError) Error() string { + var b []byte + for i, err := range e.errs { + if i > 0 { + b = append(b, '\n') + } + b = append(b, err.Error()...) + } + return string(b) +} diff --git a/go-controller/vendor/github.com/containernetworking/cni/pkg/invoke/delegate.go b/go-controller/vendor/github.com/containernetworking/cni/pkg/invoke/delegate.go index 8defe4dd39..c8b548e7c6 100644 --- a/go-controller/vendor/github.com/containernetworking/cni/pkg/invoke/delegate.go +++ b/go-controller/vendor/github.com/containernetworking/cni/pkg/invoke/delegate.go @@ -51,25 +51,34 @@ func DelegateAdd(ctx context.Context, delegatePlugin string, netconf []byte, exe // DelegateCheck calls the given delegate plugin with the CNI CHECK action and // JSON configuration func DelegateCheck(ctx context.Context, delegatePlugin string, netconf []byte, exec Exec) error { + return delegateNoResult(ctx, delegatePlugin, netconf, exec, "CHECK") +} + +func delegateNoResult(ctx context.Context, delegatePlugin string, netconf []byte, exec Exec, verb string) error { pluginPath, realExec, err := delegateCommon(delegatePlugin, exec) if err != nil { return err } - // DelegateCheck will override the original CNI_COMMAND env from process with CHECK - return ExecPluginWithoutResult(ctx, pluginPath, netconf, delegateArgs("CHECK"), realExec) + return ExecPluginWithoutResult(ctx, pluginPath, netconf, delegateArgs(verb), realExec) } // DelegateDel calls the given delegate plugin with the CNI DEL action and // JSON configuration func DelegateDel(ctx context.Context, delegatePlugin string, netconf []byte, exec Exec) error { - pluginPath, realExec, err := delegateCommon(delegatePlugin, exec) - if err != nil { - return err - } + return delegateNoResult(ctx, delegatePlugin, netconf, exec, "DEL") +} - // DelegateDel will override the original CNI_COMMAND env from process with DEL - return ExecPluginWithoutResult(ctx, pluginPath, netconf, delegateArgs("DEL"), realExec) +// DelegateStatus calls the given delegate plugin with the CNI STATUS action and +// JSON configuration +func DelegateStatus(ctx context.Context, delegatePlugin string, netconf []byte, exec Exec) error { + return delegateNoResult(ctx, delegatePlugin, netconf, exec, "STATUS") +} + +// DelegateGC calls the given delegate plugin with the CNI GC action and +// JSON configuration +func DelegateGC(ctx context.Context, delegatePlugin string, netconf []byte, exec Exec) error { + return delegateNoResult(ctx, delegatePlugin, netconf, exec, "GC") } // return CNIArgs used by delegation diff --git a/go-controller/vendor/github.com/containernetworking/cni/pkg/invoke/exec.go b/go-controller/vendor/github.com/containernetworking/cni/pkg/invoke/exec.go index 3ad07aa8f2..a5e015fc92 100644 --- a/go-controller/vendor/github.com/containernetworking/cni/pkg/invoke/exec.go +++ b/go-controller/vendor/github.com/containernetworking/cni/pkg/invoke/exec.go @@ -81,17 +81,17 @@ func fixupResultVersion(netconf, result []byte) (string, []byte, error) { // object to ExecPluginWithResult() to verify the incoming stdin and environment // and provide a tailored response: // -//import ( +// import ( // "encoding/json" // "path" // "strings" -//) +// ) // -//type fakeExec struct { +// type fakeExec struct { // version.PluginDecoder -//} +// } // -//func (f *fakeExec) ExecPlugin(pluginPath string, stdinData []byte, environ []string) ([]byte, error) { +// func (f *fakeExec) ExecPlugin(pluginPath string, stdinData []byte, environ []string) ([]byte, error) { // net := &types.NetConf{} // err := json.Unmarshal(stdinData, net) // if err != nil { @@ -109,14 +109,14 @@ func fixupResultVersion(netconf, result []byte) (string, []byte, error) { // } // } // return []byte("{\"CNIVersion\":\"0.4.0\"}"), nil -//} +// } // -//func (f *fakeExec) FindInPath(plugin string, paths []string) (string, error) { +// func (f *fakeExec) FindInPath(plugin string, paths []string) (string, error) { // if len(paths) > 0 { // return path.Join(paths[0], plugin), nil // } // return "", fmt.Errorf("failed to find plugin %s in paths %v", plugin, paths) -//} +// } func ExecPluginWithResult(ctx context.Context, pluginPath string, netconf []byte, args CNIArgs, exec Exec) (types.Result, error) { if exec == nil { diff --git a/go-controller/vendor/github.com/containernetworking/cni/pkg/invoke/os_unix.go b/go-controller/vendor/github.com/containernetworking/cni/pkg/invoke/os_unix.go index 9bcfb45536..ed0999bd0e 100644 --- a/go-controller/vendor/github.com/containernetworking/cni/pkg/invoke/os_unix.go +++ b/go-controller/vendor/github.com/containernetworking/cni/pkg/invoke/os_unix.go @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris // +build darwin dragonfly freebsd linux netbsd openbsd solaris package invoke diff --git a/go-controller/vendor/github.com/containernetworking/cni/pkg/ns/ns_linux.go b/go-controller/vendor/github.com/containernetworking/cni/pkg/ns/ns_linux.go new file mode 100644 index 0000000000..3d58e75d6c --- /dev/null +++ b/go-controller/vendor/github.com/containernetworking/cni/pkg/ns/ns_linux.go @@ -0,0 +1,50 @@ +// Copyright 2022 CNI authors +// +// 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 ns + +import ( + "runtime" + + "github.com/vishvananda/netns" + + "github.com/containernetworking/cni/pkg/types" +) + +// Returns an object representing the current OS thread's network namespace +func getCurrentNS() (netns.NsHandle, error) { + // Lock the thread in case other goroutine executes in it and changes its + // network namespace after getCurrentThreadNetNSPath(), otherwise it might + // return an unexpected network namespace. + runtime.LockOSThread() + defer runtime.UnlockOSThread() + return netns.Get() +} + +func CheckNetNS(nsPath string) (bool, *types.Error) { + ns, err := netns.GetFromPath(nsPath) + // Let plugins check whether nsPath from args is valid. Also support CNI DEL for empty nsPath as already-deleted nsPath. + if err != nil { + return false, nil + } + defer ns.Close() + + pluginNS, err := getCurrentNS() + if err != nil { + return false, types.NewError(types.ErrInvalidNetNS, "get plugin's netns failed", "") + } + defer pluginNS.Close() + + return pluginNS.Equal(ns), nil +} diff --git a/go-controller/vendor/github.com/containernetworking/cni/pkg/ns/ns_windows.go b/go-controller/vendor/github.com/containernetworking/cni/pkg/ns/ns_windows.go new file mode 100644 index 0000000000..cffe136178 --- /dev/null +++ b/go-controller/vendor/github.com/containernetworking/cni/pkg/ns/ns_windows.go @@ -0,0 +1,21 @@ +// Copyright 2022 CNI authors +// +// 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 ns + +import "github.com/containernetworking/cni/pkg/types" + +func CheckNetNS(nsPath string) (bool, *types.Error) { + return false, nil +} diff --git a/go-controller/vendor/github.com/containernetworking/cni/pkg/skel/skel.go b/go-controller/vendor/github.com/containernetworking/cni/pkg/skel/skel.go index cb8781972d..f29cf34594 100644 --- a/go-controller/vendor/github.com/containernetworking/cni/pkg/skel/skel.go +++ b/go-controller/vendor/github.com/containernetworking/cni/pkg/skel/skel.go @@ -19,13 +19,14 @@ package skel import ( "bytes" "encoding/json" + "errors" "fmt" "io" - "io/ioutil" "log" "os" "strings" + "github.com/containernetworking/cni/pkg/ns" "github.com/containernetworking/cni/pkg/types" "github.com/containernetworking/cni/pkg/utils" "github.com/containernetworking/cni/pkg/version" @@ -34,12 +35,13 @@ import ( // CmdArgs captures all the arguments passed in to the plugin // via both env vars and stdin type CmdArgs struct { - ContainerID string - Netns string - IfName string - Args string - Path string - StdinData []byte + ContainerID string + Netns string + IfName string + Args string + Path string + NetnsOverride string + StdinData []byte } type dispatcher struct { @@ -55,21 +57,25 @@ type dispatcher struct { type reqForCmdEntry map[string]bool func (t *dispatcher) getCmdArgsFromEnv() (string, *CmdArgs, *types.Error) { - var cmd, contID, netns, ifName, args, path string + var cmd, contID, netns, ifName, args, path, netnsOverride string vars := []struct { - name string - val *string - reqForCmd reqForCmdEntry + name string + val *string + reqForCmd reqForCmdEntry + validateFn func(string) *types.Error }{ { "CNI_COMMAND", &cmd, reqForCmdEntry{ - "ADD": true, - "CHECK": true, - "DEL": true, + "ADD": true, + "CHECK": true, + "DEL": true, + "GC": true, + "STATUS": true, }, + nil, }, { "CNI_CONTAINERID", @@ -79,6 +85,7 @@ func (t *dispatcher) getCmdArgsFromEnv() (string, *CmdArgs, *types.Error) { "CHECK": true, "DEL": true, }, + utils.ValidateContainerID, }, { "CNI_NETNS", @@ -88,6 +95,7 @@ func (t *dispatcher) getCmdArgsFromEnv() (string, *CmdArgs, *types.Error) { "CHECK": true, "DEL": false, }, + nil, }, { "CNI_IFNAME", @@ -97,6 +105,7 @@ func (t *dispatcher) getCmdArgsFromEnv() (string, *CmdArgs, *types.Error) { "CHECK": true, "DEL": true, }, + utils.ValidateInterfaceName, }, { "CNI_ARGS", @@ -106,15 +115,29 @@ func (t *dispatcher) getCmdArgsFromEnv() (string, *CmdArgs, *types.Error) { "CHECK": false, "DEL": false, }, + nil, }, { "CNI_PATH", &path, reqForCmdEntry{ - "ADD": true, - "CHECK": true, - "DEL": true, + "ADD": true, + "CHECK": true, + "DEL": true, + "GC": true, + "STATUS": true, + }, + nil, + }, + { + "CNI_NETNS_OVERRIDE", + &netnsOverride, + reqForCmdEntry{ + "ADD": false, + "CHECK": false, + "DEL": false, }, + nil, }, } @@ -125,6 +148,10 @@ func (t *dispatcher) getCmdArgsFromEnv() (string, *CmdArgs, *types.Error) { if v.reqForCmd[cmd] || v.name == "CNI_COMMAND" { argsMissing = append(argsMissing, v.name) } + } else if v.reqForCmd[cmd] && v.validateFn != nil { + if err := v.validateFn(*v.val); err != nil { + return "", nil, err + } } } @@ -137,18 +164,25 @@ func (t *dispatcher) getCmdArgsFromEnv() (string, *CmdArgs, *types.Error) { t.Stdin = bytes.NewReader(nil) } - stdinData, err := ioutil.ReadAll(t.Stdin) + stdinData, err := io.ReadAll(t.Stdin) if err != nil { return "", nil, types.NewError(types.ErrIOFailure, fmt.Sprintf("error reading from stdin: %v", err), "") } + if cmd != "VERSION" { + if err := validateConfig(stdinData); err != nil { + return "", nil, err + } + } + cmdArgs := &CmdArgs{ - ContainerID: contID, - Netns: netns, - IfName: ifName, - Args: args, - Path: path, - StdinData: stdinData, + ContainerID: contID, + Netns: netns, + IfName: ifName, + Args: args, + Path: path, + StdinData: stdinData, + NetnsOverride: netnsOverride, } return cmd, cmdArgs, nil } @@ -163,8 +197,13 @@ func (t *dispatcher) checkVersionAndCall(cmdArgs *CmdArgs, pluginVersionInfo ver return types.NewError(types.ErrIncompatibleCNIVersion, "incompatible CNI versions", verErr.Details()) } + if toCall == nil { + return nil + } + if err = toCall(cmdArgs); err != nil { - if e, ok := err.(*types.Error); ok { + var e *types.Error + if errors.As(err, &e) { // don't wrap Error in Error return e } @@ -190,7 +229,7 @@ func validateConfig(jsonBytes []byte) *types.Error { return nil } -func (t *dispatcher) pluginMain(cmdAdd, cmdCheck, cmdDel func(_ *CmdArgs) error, versionInfo version.PluginInfo, about string) *types.Error { +func (t *dispatcher) pluginMain(funcs CNIFuncs, versionInfo version.PluginInfo, about string) *types.Error { cmd, cmdArgs, err := t.getCmdArgsFromEnv() if err != nil { // Print the about string to stderr when no command is set @@ -202,21 +241,20 @@ func (t *dispatcher) pluginMain(cmdAdd, cmdCheck, cmdDel func(_ *CmdArgs) error, return err } - if cmd != "VERSION" { - if err = validateConfig(cmdArgs.StdinData); err != nil { - return err - } - if err = utils.ValidateContainerID(cmdArgs.ContainerID); err != nil { + switch cmd { + case "ADD": + err = t.checkVersionAndCall(cmdArgs, versionInfo, funcs.Add) + if err != nil { return err } - if err = utils.ValidateInterfaceName(cmdArgs.IfName); err != nil { - return err + if strings.ToUpper(cmdArgs.NetnsOverride) != "TRUE" && cmdArgs.NetnsOverride != "1" { + isPluginNetNS, checkErr := ns.CheckNetNS(cmdArgs.Netns) + if checkErr != nil { + return checkErr + } else if isPluginNetNS { + return types.NewError(types.ErrInvalidNetNS, "plugin's netns and netns from CNI_NETNS should not be the same", "") + } } - } - - switch cmd { - case "ADD": - err = t.checkVersionAndCall(cmdArgs, versionInfo, cmdAdd) case "CHECK": configVersion, err := t.ConfVersionDecoder.Decode(cmdArgs.StdinData) if err != nil { @@ -232,7 +270,7 @@ func (t *dispatcher) pluginMain(cmdAdd, cmdCheck, cmdDel func(_ *CmdArgs) error, if err != nil { return types.NewError(types.ErrDecodingFailure, err.Error(), "") } else if gtet { - if err := t.checkVersionAndCall(cmdArgs, versionInfo, cmdCheck); err != nil { + if err := t.checkVersionAndCall(cmdArgs, versionInfo, funcs.Check); err != nil { return err } return nil @@ -240,7 +278,62 @@ func (t *dispatcher) pluginMain(cmdAdd, cmdCheck, cmdDel func(_ *CmdArgs) error, } return types.NewError(types.ErrIncompatibleCNIVersion, "plugin version does not allow CHECK", "") case "DEL": - err = t.checkVersionAndCall(cmdArgs, versionInfo, cmdDel) + err = t.checkVersionAndCall(cmdArgs, versionInfo, funcs.Del) + if err != nil { + return err + } + if strings.ToUpper(cmdArgs.NetnsOverride) != "TRUE" && cmdArgs.NetnsOverride != "1" { + isPluginNetNS, checkErr := ns.CheckNetNS(cmdArgs.Netns) + if checkErr != nil { + return checkErr + } else if isPluginNetNS { + return types.NewError(types.ErrInvalidNetNS, "plugin's netns and netns from CNI_NETNS should not be the same", "") + } + } + case "GC": + configVersion, err := t.ConfVersionDecoder.Decode(cmdArgs.StdinData) + if err != nil { + return types.NewError(types.ErrDecodingFailure, err.Error(), "") + } + if gtet, err := version.GreaterThanOrEqualTo(configVersion, "1.1.0"); err != nil { + return types.NewError(types.ErrDecodingFailure, err.Error(), "") + } else if !gtet { + return types.NewError(types.ErrIncompatibleCNIVersion, "config version does not allow GC", "") + } + for _, pluginVersion := range versionInfo.SupportedVersions() { + gtet, err := version.GreaterThanOrEqualTo(pluginVersion, configVersion) + if err != nil { + return types.NewError(types.ErrDecodingFailure, err.Error(), "") + } else if gtet { + if err := t.checkVersionAndCall(cmdArgs, versionInfo, funcs.GC); err != nil { + return err + } + return nil + } + } + return types.NewError(types.ErrIncompatibleCNIVersion, "plugin version does not allow GC", "") + case "STATUS": + configVersion, err := t.ConfVersionDecoder.Decode(cmdArgs.StdinData) + if err != nil { + return types.NewError(types.ErrDecodingFailure, err.Error(), "") + } + if gtet, err := version.GreaterThanOrEqualTo(configVersion, "1.1.0"); err != nil { + return types.NewError(types.ErrDecodingFailure, err.Error(), "") + } else if !gtet { + return types.NewError(types.ErrIncompatibleCNIVersion, "config version does not allow STATUS", "") + } + for _, pluginVersion := range versionInfo.SupportedVersions() { + gtet, err := version.GreaterThanOrEqualTo(pluginVersion, configVersion) + if err != nil { + return types.NewError(types.ErrDecodingFailure, err.Error(), "") + } else if gtet { + if err := t.checkVersionAndCall(cmdArgs, versionInfo, funcs.Status); err != nil { + return err + } + return nil + } + } + return types.NewError(types.ErrIncompatibleCNIVersion, "plugin version does not allow STATUS", "") case "VERSION": if err := versionInfo.Encode(t.Stdout); err != nil { return types.NewError(types.ErrIOFailure, err.Error(), "") @@ -264,13 +357,63 @@ func (t *dispatcher) pluginMain(cmdAdd, cmdCheck, cmdDel func(_ *CmdArgs) error, // // To let this package automatically handle errors and call os.Exit(1) for you, // use PluginMain() instead. +// +// Deprecated: Use github.com/containernetworking/cni/pkg/skel.PluginMainFuncsWithError instead. func PluginMainWithError(cmdAdd, cmdCheck, cmdDel func(_ *CmdArgs) error, versionInfo version.PluginInfo, about string) *types.Error { + return PluginMainFuncsWithError(CNIFuncs{Add: cmdAdd, Check: cmdCheck, Del: cmdDel}, versionInfo, about) +} + +// CNIFuncs contains a group of callback command funcs to be passed in as +// parameters to the core "main" for a plugin. +type CNIFuncs struct { + Add func(_ *CmdArgs) error + Del func(_ *CmdArgs) error + Check func(_ *CmdArgs) error + GC func(_ *CmdArgs) error + Status func(_ *CmdArgs) error +} + +// PluginMainFuncsWithError is the core "main" for a plugin. It accepts +// callback functions defined within CNIFuncs and returns an error. +// +// The caller must also specify what CNI spec versions the plugin supports. +// +// It is the responsibility of the caller to check for non-nil error return. +// +// For a plugin to comply with the CNI spec, it must print any error to stdout +// as JSON and then exit with nonzero status code. +// +// To let this package automatically handle errors and call os.Exit(1) for you, +// use PluginMainFuncs() instead. +func PluginMainFuncsWithError(funcs CNIFuncs, versionInfo version.PluginInfo, about string) *types.Error { return (&dispatcher{ Getenv: os.Getenv, Stdin: os.Stdin, Stdout: os.Stdout, Stderr: os.Stderr, - }).pluginMain(cmdAdd, cmdCheck, cmdDel, versionInfo, about) + }).pluginMain(funcs, versionInfo, about) +} + +// PluginMainFuncs is the core "main" for a plugin which includes automatic error handling. +// This is a newer alternative func to PluginMain which abstracts CNI commands within a +// CNIFuncs interface. +// +// The caller must also specify what CNI spec versions the plugin supports. +// +// The caller can specify an "about" string, which is printed on stderr +// when no CNI_COMMAND is specified. The recommended output is "CNI plugin v" +// +// When an error occurs in any func in CNIFuncs, PluginMainFuncs will print the error +// as JSON to stdout and call os.Exit(1). +// +// To have more control over error handling, use PluginMainFuncsWithError() instead. +func PluginMainFuncs(funcs CNIFuncs, versionInfo version.PluginInfo, about string) { + if e := PluginMainFuncsWithError(funcs, versionInfo, about); e != nil { + if err := e.Print(); err != nil { + log.Print("Error writing error JSON to stdout: ", err) + } + os.Exit(1) + } } // PluginMain is the core "main" for a plugin which includes automatic error handling. @@ -284,6 +427,8 @@ func PluginMainWithError(cmdAdd, cmdCheck, cmdDel func(_ *CmdArgs) error, versio // as JSON to stdout and call os.Exit(1). // // To have more control over error handling, use PluginMainWithError() instead. +// +// Deprecated: Use github.com/containernetworking/cni/pkg/skel.PluginMainFuncs instead. func PluginMain(cmdAdd, cmdCheck, cmdDel func(_ *CmdArgs) error, versionInfo version.PluginInfo, about string) { if e := PluginMainWithError(cmdAdd, cmdCheck, cmdDel, versionInfo, about); e != nil { if err := e.Print(); err != nil { diff --git a/go-controller/vendor/github.com/containernetworking/cni/pkg/types/100/types.go b/go-controller/vendor/github.com/containernetworking/cni/pkg/types/100/types.go index 0e1e8b857b..f58b91206d 100644 --- a/go-controller/vendor/github.com/containernetworking/cni/pkg/types/100/types.go +++ b/go-controller/vendor/github.com/containernetworking/cni/pkg/types/100/types.go @@ -26,9 +26,10 @@ import ( convert "github.com/containernetworking/cni/pkg/types/internal" ) -const ImplementedSpecVersion string = "1.0.0" +// The types did not change between v1.0 and v1.1 +const ImplementedSpecVersion string = "1.1.0" -var supportedVersions = []string{ImplementedSpecVersion} +var supportedVersions = []string{"1.0.0", "1.1.0"} // Register converters for all versions less than the implemented spec version func init() { @@ -38,10 +39,14 @@ func init() { convert.RegisterConverter("0.3.0", supportedVersions, convertFrom04x) convert.RegisterConverter("0.3.1", supportedVersions, convertFrom04x) convert.RegisterConverter("0.4.0", supportedVersions, convertFrom04x) + convert.RegisterConverter("1.0.0", []string{"1.1.0"}, convertFrom100) // Down-converters convert.RegisterConverter("1.0.0", []string{"0.3.0", "0.3.1", "0.4.0"}, convertTo04x) convert.RegisterConverter("1.0.0", []string{"0.1.0", "0.2.0"}, convertTo02x) + convert.RegisterConverter("1.1.0", []string{"0.3.0", "0.3.1", "0.4.0"}, convertTo04x) + convert.RegisterConverter("1.1.0", []string{"0.1.0", "0.2.0"}, convertTo02x) + convert.RegisterConverter("1.1.0", []string{"1.0.0"}, convertFrom100) // Creator convert.RegisterCreator(supportedVersions, NewResult) @@ -90,12 +95,49 @@ type Result struct { DNS types.DNS `json:"dns,omitempty"` } +// Note: DNS should be omit if DNS is empty but default Marshal function +// will output empty structure hence need to write a Marshal function +func (r *Result) MarshalJSON() ([]byte, error) { + // use type alias to escape recursion for json.Marshal() to MarshalJSON() + type fixObjType = Result + + bytes, err := json.Marshal(fixObjType(*r)) //nolint:all + if err != nil { + return nil, err + } + + fixupObj := make(map[string]interface{}) + if err := json.Unmarshal(bytes, &fixupObj); err != nil { + return nil, err + } + + if r.DNS.IsEmpty() { + delete(fixupObj, "dns") + } + + return json.Marshal(fixupObj) +} + +// convertFrom100 does nothing except set the version; the types are the same +func convertFrom100(from types.Result, toVersion string) (types.Result, error) { + fromResult := from.(*Result) + + result := &Result{ + CNIVersion: toVersion, + Interfaces: fromResult.Interfaces, + IPs: fromResult.IPs, + Routes: fromResult.Routes, + DNS: fromResult.DNS, + } + return result, nil +} + func convertFrom02x(from types.Result, toVersion string) (types.Result, error) { result040, err := convert.Convert(from, "0.4.0") if err != nil { return nil, err } - result100, err := convertFrom04x(result040, ImplementedSpecVersion) + result100, err := convertFrom04x(result040, toVersion) if err != nil { return nil, err } @@ -226,9 +268,12 @@ func (r *Result) PrintTo(writer io.Writer) error { // Interface contains values about the created interfaces type Interface struct { - Name string `json:"name"` - Mac string `json:"mac,omitempty"` - Sandbox string `json:"sandbox,omitempty"` + Name string `json:"name"` + Mac string `json:"mac,omitempty"` + Mtu int `json:"mtu,omitempty"` + Sandbox string `json:"sandbox,omitempty"` + SocketPath string `json:"socketPath,omitempty"` + PciID string `json:"pciID,omitempty"` } func (i *Interface) String() string { diff --git a/go-controller/vendor/github.com/containernetworking/cni/pkg/types/args.go b/go-controller/vendor/github.com/containernetworking/cni/pkg/types/args.go index 7516f03ef5..68a602bfdb 100644 --- a/go-controller/vendor/github.com/containernetworking/cni/pkg/types/args.go +++ b/go-controller/vendor/github.com/containernetworking/cni/pkg/types/args.go @@ -26,8 +26,8 @@ import ( type UnmarshallableBool bool // UnmarshalText implements the encoding.TextUnmarshaler interface. -// Returns boolean true if the string is "1" or "[Tt]rue" -// Returns boolean false if the string is "0" or "[Ff]alse" +// Returns boolean true if the string is "1" or "true" or "True" +// Returns boolean false if the string is "0" or "false" or "False” func (b *UnmarshallableBool) UnmarshalText(data []byte) error { s := strings.ToLower(string(data)) switch s { diff --git a/go-controller/vendor/github.com/containernetworking/cni/pkg/types/create/create.go b/go-controller/vendor/github.com/containernetworking/cni/pkg/types/create/create.go index ed28b33e8e..452cb62201 100644 --- a/go-controller/vendor/github.com/containernetworking/cni/pkg/types/create/create.go +++ b/go-controller/vendor/github.com/containernetworking/cni/pkg/types/create/create.go @@ -19,6 +19,9 @@ import ( "fmt" "github.com/containernetworking/cni/pkg/types" + _ "github.com/containernetworking/cni/pkg/types/020" + _ "github.com/containernetworking/cni/pkg/types/040" + _ "github.com/containernetworking/cni/pkg/types/100" convert "github.com/containernetworking/cni/pkg/types/internal" ) diff --git a/go-controller/vendor/github.com/containernetworking/cni/pkg/types/types.go b/go-controller/vendor/github.com/containernetworking/cni/pkg/types/types.go index fba17dfc0f..193ac46ef8 100644 --- a/go-controller/vendor/github.com/containernetworking/cni/pkg/types/types.go +++ b/go-controller/vendor/github.com/containernetworking/cni/pkg/types/types.go @@ -64,16 +64,55 @@ type NetConf struct { Type string `json:"type,omitempty"` Capabilities map[string]bool `json:"capabilities,omitempty"` IPAM IPAM `json:"ipam,omitempty"` - DNS DNS `json:"dns"` + DNS DNS `json:"dns,omitempty"` RawPrevResult map[string]interface{} `json:"prevResult,omitempty"` PrevResult Result `json:"-"` + + // ValidAttachments is only supplied when executing a GC operation + ValidAttachments []GCAttachment `json:"cni.dev/valid-attachments,omitempty"` +} + +// GCAttachment is the parameters to a GC call -- namely, +// the container ID and ifname pair that represents a +// still-valid attachment. +type GCAttachment struct { + ContainerID string `json:"containerID"` + IfName string `json:"ifname"` +} + +// Note: DNS should be omit if DNS is empty but default Marshal function +// will output empty structure hence need to write a Marshal function +func (n *NetConf) MarshalJSON() ([]byte, error) { + // use type alias to escape recursion for json.Marshal() to MarshalJSON() + type fixObjType = NetConf + + bytes, err := json.Marshal(fixObjType(*n)) //nolint:all + if err != nil { + return nil, err + } + + fixupObj := make(map[string]interface{}) + if err := json.Unmarshal(bytes, &fixupObj); err != nil { + return nil, err + } + + if n.DNS.IsEmpty() { + delete(fixupObj, "dns") + } + + return json.Marshal(fixupObj) } type IPAM struct { Type string `json:"type,omitempty"` } +// IsEmpty returns true if IPAM structure has no value, otherwise return false +func (i *IPAM) IsEmpty() bool { + return i.Type == "" +} + // NetConfList describes an ordered list of networks. type NetConfList struct { CNIVersion string `json:"cniVersion,omitempty"` @@ -116,31 +155,48 @@ type DNS struct { Options []string `json:"options,omitempty"` } +// IsEmpty returns true if DNS structure has no value, otherwise return false +func (d *DNS) IsEmpty() bool { + if len(d.Nameservers) == 0 && d.Domain == "" && len(d.Search) == 0 && len(d.Options) == 0 { + return true + } + return false +} + func (d *DNS) Copy() *DNS { if d == nil { return nil } to := &DNS{Domain: d.Domain} - for _, ns := range d.Nameservers { - to.Nameservers = append(to.Nameservers, ns) - } - for _, s := range d.Search { - to.Search = append(to.Search, s) - } - for _, o := range d.Options { - to.Options = append(to.Options, o) - } + to.Nameservers = append(to.Nameservers, d.Nameservers...) + to.Search = append(to.Search, d.Search...) + to.Options = append(to.Options, d.Options...) return to } type Route struct { - Dst net.IPNet - GW net.IP + Dst net.IPNet + GW net.IP + MTU int + AdvMSS int + Priority int + Table *int + Scope *int } func (r *Route) String() string { - return fmt.Sprintf("%+v", *r) + table := "" + if r.Table != nil { + table = fmt.Sprintf("%d", *r.Table) + } + + scope := "" + if r.Scope != nil { + scope = fmt.Sprintf("%d", *r.Scope) + } + + return fmt.Sprintf("{Dst:%+v GW:%v MTU:%d AdvMSS:%d Priority:%d Table:%s Scope:%s}", r.Dst, r.GW, r.MTU, r.AdvMSS, r.Priority, table, scope) } func (r *Route) Copy() *Route { @@ -148,14 +204,30 @@ func (r *Route) Copy() *Route { return nil } - return &Route{ - Dst: r.Dst, - GW: r.GW, + route := &Route{ + Dst: r.Dst, + GW: r.GW, + MTU: r.MTU, + AdvMSS: r.AdvMSS, + Priority: r.Priority, + Scope: r.Scope, + } + + if r.Table != nil { + table := *r.Table + route.Table = &table } + + if r.Scope != nil { + scope := *r.Scope + route.Scope = &scope + } + + return route } // Well known error codes -// see https://github.com/containernetworking/cni/blob/master/SPEC.md#well-known-error-codes +// see https://github.com/containernetworking/cni/blob/main/SPEC.md#well-known-error-codes const ( ErrUnknown uint = iota // 0 ErrIncompatibleCNIVersion // 1 @@ -165,6 +237,7 @@ const ( ErrIOFailure // 5 ErrDecodingFailure // 6 ErrInvalidNetworkConfig // 7 + ErrInvalidNetNS // 8 ErrTryAgainLater uint = 11 ErrInternal uint = 999 ) @@ -200,8 +273,13 @@ func (e *Error) Print() error { // JSON (un)marshallable types type route struct { - Dst IPNet `json:"dst"` - GW net.IP `json:"gw,omitempty"` + Dst IPNet `json:"dst"` + GW net.IP `json:"gw,omitempty"` + MTU int `json:"mtu,omitempty"` + AdvMSS int `json:"advmss,omitempty"` + Priority int `json:"priority,omitempty"` + Table *int `json:"table,omitempty"` + Scope *int `json:"scope,omitempty"` } func (r *Route) UnmarshalJSON(data []byte) error { @@ -212,13 +290,24 @@ func (r *Route) UnmarshalJSON(data []byte) error { r.Dst = net.IPNet(rt.Dst) r.GW = rt.GW + r.MTU = rt.MTU + r.AdvMSS = rt.AdvMSS + r.Priority = rt.Priority + r.Table = rt.Table + r.Scope = rt.Scope + return nil } func (r Route) MarshalJSON() ([]byte, error) { rt := route{ - Dst: IPNet(r.Dst), - GW: r.GW, + Dst: IPNet(r.Dst), + GW: r.GW, + MTU: r.MTU, + AdvMSS: r.AdvMSS, + Priority: r.Priority, + Table: r.Table, + Scope: r.Scope, } return json.Marshal(rt) diff --git a/go-controller/vendor/github.com/containernetworking/cni/pkg/utils/utils.go b/go-controller/vendor/github.com/containernetworking/cni/pkg/utils/utils.go index b8ec388745..1981d25569 100644 --- a/go-controller/vendor/github.com/containernetworking/cni/pkg/utils/utils.go +++ b/go-controller/vendor/github.com/containernetworking/cni/pkg/utils/utils.go @@ -36,7 +36,6 @@ var cniReg = regexp.MustCompile(`^` + cniValidNameChars + `*$`) // ValidateContainerID will validate that the supplied containerID is not empty does not contain invalid characters func ValidateContainerID(containerID string) *types.Error { - if containerID == "" { return types.NewError(types.ErrUnknownContainer, "missing containerID", "") } @@ -48,7 +47,6 @@ func ValidateContainerID(containerID string) *types.Error { // ValidateNetworkName will validate that the supplied networkName does not contain invalid characters func ValidateNetworkName(networkName string) *types.Error { - if networkName == "" { return types.NewError(types.ErrInvalidNetworkConfig, "missing network name:", "") } @@ -58,11 +56,11 @@ func ValidateNetworkName(networkName string) *types.Error { return nil } -// ValidateInterfaceName will validate the interface name based on the three rules below +// ValidateInterfaceName will validate the interface name based on the four rules below // 1. The name must not be empty // 2. The name must be less than 16 characters // 3. The name must not be "." or ".." -// 3. The name must not contain / or : or any whitespace characters +// 4. The name must not contain / or : or any whitespace characters // ref to https://github.com/torvalds/linux/blob/master/net/core/dev.c#L1024 func ValidateInterfaceName(ifName string) *types.Error { if len(ifName) == 0 { diff --git a/go-controller/vendor/github.com/containernetworking/cni/pkg/version/version.go b/go-controller/vendor/github.com/containernetworking/cni/pkg/version/version.go index 1326f8038e..a4d442c8ec 100644 --- a/go-controller/vendor/github.com/containernetworking/cni/pkg/version/version.go +++ b/go-controller/vendor/github.com/containernetworking/cni/pkg/version/version.go @@ -19,13 +19,12 @@ import ( "fmt" "github.com/containernetworking/cni/pkg/types" - types100 "github.com/containernetworking/cni/pkg/types/100" "github.com/containernetworking/cni/pkg/types/create" ) // Current reports the version of the CNI spec implemented by this library func Current() string { - return types100.ImplementedSpecVersion + return "1.1.0" } // Legacy PluginInfo describes a plugin that is backwards compatible with the @@ -35,8 +34,10 @@ func Current() string { // // Any future CNI spec versions which meet this definition should be added to // this list. -var Legacy = PluginSupports("0.1.0", "0.2.0") -var All = PluginSupports("0.1.0", "0.2.0", "0.3.0", "0.3.1", "0.4.0", "1.0.0") +var ( + Legacy = PluginSupports("0.1.0", "0.2.0") + All = PluginSupports("0.1.0", "0.2.0", "0.3.0", "0.3.1", "0.4.0", "1.0.0", "1.1.0") +) // VersionsFrom returns a list of versions starting from min, inclusive func VersionsStartingFrom(min string) PluginInfo { diff --git a/go-controller/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1/types.go b/go-controller/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1/types.go index 7e202ed8d0..042a5867e0 100644 --- a/go-controller/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1/types.go +++ b/go-controller/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1/types.go @@ -2,9 +2,9 @@ package v1 import ( "encoding/json" - "errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "net" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) // +genclient @@ -107,6 +107,7 @@ type NetworkStatus struct { Interface string `json:"interface,omitempty"` IPs []string `json:"ips,omitempty"` Mac string `json:"mac,omitempty"` + Mtu int `json:"mtu,omitempty"` Default bool `json:"default,omitempty"` DNS DNS `json:"dns,omitempty"` DeviceInfo *DeviceInfo `json:"device-info,omitempty"` @@ -176,9 +177,6 @@ func (nse *NetworkSelectionElement) UnmarshalJSON(b []byte) error { if err := json.Unmarshal(b, &netSelectionElement); err != nil { return err } - if len(netSelectionElement.IPRequest) > 0 && netSelectionElement.IPAMClaimReference != "" { - return TooManyIPSources - } *nse = NetworkSelectionElement(netSelectionElement) return nil } @@ -197,5 +195,3 @@ type NoK8sNetworkError struct { } func (e *NoK8sNetworkError) Error() string { return string(e.Message) } - -var TooManyIPSources = errors.New("cannot provide a static IP and a reference of an IPAM claim in the same network selection element") diff --git a/go-controller/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/utils/net-attach-def.go b/go-controller/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/utils/net-attach-def.go index 4bca1645fb..acebe13a4a 100644 --- a/go-controller/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/utils/net-attach-def.go +++ b/go-controller/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/utils/net-attach-def.go @@ -122,6 +122,117 @@ func GetNetworkStatus(pod *corev1.Pod) ([]v1.NetworkStatus, error) { return netStatuses, err } +// gatewayInterfaceIndex determines the index of the first interface that has a gateway +func gatewayInterfaceIndex(ips []*cni100.IPConfig) int { + for _, ipConfig := range ips { + if ipConfig.Gateway != nil && ipConfig.Interface != nil { + return *ipConfig.Interface + } + } + return -1 +} + +// CreateNetworkStatuses creates an array of NetworkStatus from CNI result +// Not to be confused with CreateNetworkStatus (singular) +// This is the preferred method and picks up when CNI ADD results contain multiple container interfaces +func CreateNetworkStatuses(r cnitypes.Result, networkName string, defaultNetwork bool, dev *v1.DeviceInfo) ([]*v1.NetworkStatus, error) { + var networkStatuses []*v1.NetworkStatus + // indexMap is from original CNI result index to networkStatuses index + indexMap := make(map[int]int) + + // Convert whatever the IPAM result was into the current Result type + result, err := cni100.NewResultFromResult(r) + if err != nil { + return nil, fmt.Errorf("error converting the type.Result to cni100.Result: %v", err) + } + + if len(result.Interfaces) == 1 { + networkStatus, err := CreateNetworkStatus(r, networkName, defaultNetwork, dev) + return []*v1.NetworkStatus{networkStatus}, err + } + + // Discover default routes upfront and reuse them if necessary. + var useDefaultRoute []string + for _, route := range result.Routes { + if isDefaultRoute(route) { + useDefaultRoute = append(useDefaultRoute, route.GW.String()) + } + } + + // Same for DNS + v1dns := convertDNS(result.DNS) + + // Check for a gateway-associated interface, we'll use this later if we did to mark as the default. + gwInterfaceIdx := -1 + if defaultNetwork { + gwInterfaceIdx = gatewayInterfaceIndex(result.IPs) + } + + // Initialize NetworkStatus for each container interface (e.g. with sandbox present) + indexOfFoundPodInterface := 0 + foundFirstSandboxIface := false + didSetDefault := false + for i, iface := range result.Interfaces { + if iface.Sandbox != "" { + isDefault := false + + // If there's a gateway listed for this interface index found in the ips, we mark that interface as default + // notably, we use the first one we find. + if defaultNetwork && i == gwInterfaceIdx && !didSetDefault { + isDefault = true + didSetDefault = true + } + + // Otherwise, if we didn't find it, we use the first sandbox interface. + if defaultNetwork && gwInterfaceIdx == -1 && !foundFirstSandboxIface { + isDefault = true + foundFirstSandboxIface = true + } + + ns := &v1.NetworkStatus{ + Name: networkName, + Default: isDefault, + Interface: iface.Name, + Mac: iface.Mac, + Mtu: iface.Mtu, + IPs: []string{}, + Gateway: useDefaultRoute, + DeviceInfo: dev, + DNS: *v1dns, + } + networkStatuses = append(networkStatuses, ns) + // Map original index to the new slice index + indexMap[i] = indexOfFoundPodInterface + indexOfFoundPodInterface++ + } + } + + var defaultNetworkStatus *v1.NetworkStatus + if len(networkStatuses) > 0 { + // Set the default network status to the last network status. + defaultNetworkStatus = networkStatuses[len(networkStatuses)-1] + } + + // Map IPs to network interface based on index + for _, ipConfig := range result.IPs { + if ipConfig.Interface != nil { + originalIndex := *ipConfig.Interface + if newIndex, ok := indexMap[originalIndex]; ok { + ns := networkStatuses[newIndex] + ns.IPs = append(ns.IPs, ipConfig.Address.IP.String()) + } + } else { + // If the IPs don't specify the interface assign the IP to the default network status. This keeps the behaviour + // consistent with previous multus versions. + if defaultNetworkStatus != nil { + defaultNetworkStatus.IPs = append(defaultNetworkStatus.IPs, ipConfig.Address.IP.String()) + } + } + } + + return networkStatuses, nil +} + // CreateNetworkStatus create NetworkStatus from CNI result func CreateNetworkStatus(r cnitypes.Result, networkName string, defaultNetwork bool, dev *v1.DeviceInfo) (*v1.NetworkStatus, error) { netStatus := &v1.NetworkStatus{} @@ -139,6 +250,7 @@ func CreateNetworkStatus(r cnitypes.Result, networkName string, defaultNetwork b if ifs.Sandbox != "" { netStatus.Interface = ifs.Name netStatus.Mac = ifs.Mac + netStatus.Mtu = ifs.Mtu } } diff --git a/go-controller/vendor/modules.txt b/go-controller/vendor/modules.txt index 7636490960..e3578ea166 100644 --- a/go-controller/vendor/modules.txt +++ b/go-controller/vendor/modules.txt @@ -1,3 +1,6 @@ +# github.com/Masterminds/semver/v3 v3.2.1 +## explicit; go 1.18 +github.com/Masterminds/semver/v3 # github.com/Microsoft/go-winio v0.6.2 ## explicit; go 1.21 github.com/Microsoft/go-winio @@ -56,10 +59,11 @@ github.com/cespare/xxhash/v2 # github.com/containerd/cgroups v1.1.0 ## explicit; go 1.17 github.com/containerd/cgroups/stats/v1 -# github.com/containernetworking/cni v1.1.2 -## explicit; go 1.14 +# github.com/containernetworking/cni v1.2.0-rc1 +## explicit; go 1.18 github.com/containernetworking/cni/libcni github.com/containernetworking/cni/pkg/invoke +github.com/containernetworking/cni/pkg/ns github.com/containernetworking/cni/pkg/skel github.com/containernetworking/cni/pkg/types github.com/containernetworking/cni/pkg/types/020 @@ -229,7 +233,7 @@ github.com/k8snetworkplumbingwg/multi-networkpolicy/pkg/client/informers/externa github.com/k8snetworkplumbingwg/multi-networkpolicy/pkg/client/informers/externalversions/k8s.cni.cncf.io/v1beta2 github.com/k8snetworkplumbingwg/multi-networkpolicy/pkg/client/listers/k8s.cni.cncf.io/v1beta1 github.com/k8snetworkplumbingwg/multi-networkpolicy/pkg/client/listers/k8s.cni.cncf.io/v1beta2 -# github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.6.0 +# github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.7.7 ## explicit; go 1.21 github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1 diff --git a/test/e2e/go.mod b/test/e2e/go.mod index d9d67fb0c4..a6a913d424 100644 --- a/test/e2e/go.mod +++ b/test/e2e/go.mod @@ -8,7 +8,7 @@ require ( github.com/google/go-cmp v0.6.0 github.com/k8snetworkplumbingwg/ipamclaims v0.5.0-alpha github.com/k8snetworkplumbingwg/multi-networkpolicy v1.0.1 - github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.6.0 + github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.7.7 github.com/onsi/ginkgo/v2 v2.22.0 github.com/onsi/gomega v1.36.1 github.com/pkg/errors v0.9.1 @@ -25,6 +25,7 @@ require ( require ( cel.dev/expr v0.18.0 // indirect github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab // indirect + github.com/Masterminds/semver/v3 v3.2.1 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/NYTimes/gziphandler v1.1.1 // indirect github.com/antlr4-go/antlr/v4 v4.13.0 // indirect @@ -39,7 +40,7 @@ require ( github.com/containerd/errdefs v0.1.0 // indirect github.com/containerd/log v0.1.0 // indirect github.com/containerd/ttrpc v1.2.5 // indirect - github.com/containernetworking/cni v1.1.2 // indirect + github.com/containernetworking/cni v1.2.0-rc1 // indirect github.com/coreos/go-iptables v0.6.0 // indirect github.com/coreos/go-json v0.0.0-20230131223807-18775e0fb4fb // indirect github.com/coreos/go-semver v0.3.1 // indirect diff --git a/test/e2e/go.sum b/test/e2e/go.sum index 900d7aa612..9df045a32f 100644 --- a/test/e2e/go.sum +++ b/test/e2e/go.sum @@ -51,6 +51,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab h1:UKkYhof1njT1/xq4SEg5z+VpTgjmNeHwPGRQl7takDI= github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab/go.mod h1:3VYc5hodBMJ5+l/7J4xAyMeuM2PNuepvHlGs8yilUCA= +github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= +github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= @@ -95,8 +97,8 @@ github.com/containerd/ttrpc v1.2.5 h1:IFckT1EFQoFBMG4c3sMdT8EP3/aKfumK1msY+Ze4oL github.com/containerd/ttrpc v1.2.5/go.mod h1:YCXHsb32f+Sq5/72xHubdiJRQY9inL4a4ZQrAbN1q9o= github.com/containerd/typeurl/v2 v2.2.0 h1:6NBDbQzr7I5LHgp34xAXYF5DOTQDn05X58lsPEmzLso= github.com/containerd/typeurl/v2 v2.2.0/go.mod h1:8XOOxnyatxSWuG8OfsZXVnAF4iZfedjS/8UHSPJnX4g= -github.com/containernetworking/cni v1.1.2 h1:wtRGZVv7olUHMOqouPpn3cXJWpJgM6+EUl31EQbXALQ= -github.com/containernetworking/cni v1.1.2/go.mod h1:sDpYKmGVENF3s6uvMvGgldDWeG8dMxakj/u+i9ht9vw= +github.com/containernetworking/cni v1.2.0-rc1 h1:AKI3+pXtgY4PDLN9+50o9IaywWVuey0Jkw3Lvzp0HCY= +github.com/containernetworking/cni v1.2.0-rc1/go.mod h1:Lt0TQcZQVDju64fYxUhDziTgXCDe3Olzi9I4zZJLWHg= github.com/containernetworking/plugins v1.2.0 h1:SWgg3dQG1yzUo4d9iD8cwSVh1VqI+bP7mkPDoSfP9VU= github.com/containernetworking/plugins v1.2.0/go.mod h1:/VjX4uHecW5vVimFa1wkG4s+r/s9qIfPdqlLF4TW8c4= github.com/coreos/butane v0.18.0 h1:WDeUC/dX1MUUVPwiqsQetQZsShNKk+2lrRXlC4ZhnZA= @@ -335,8 +337,8 @@ github.com/k8snetworkplumbingwg/ipamclaims v0.5.0-alpha h1:b3iHeks/KTzhG2dNanaUZ github.com/k8snetworkplumbingwg/ipamclaims v0.5.0-alpha/go.mod h1:MGaMX1tJ7MlHDee4/xmqp3guQh+eDiuCLAauqD9K11Q= github.com/k8snetworkplumbingwg/multi-networkpolicy v1.0.1 h1:Egj1hEVYNXWFlKpgzAXxe/2o8VNiVcAJLrKzlinILQo= github.com/k8snetworkplumbingwg/multi-networkpolicy v1.0.1/go.mod h1:kEJ4WM849yNmXekuSXLRwb+LaZ9usC06O8JgoAIq+f4= -github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.6.0 h1:BT3ghAY0q7lWib9rz+tVXDFkm27dJV6SLCn7TunZwo4= -github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.6.0/go.mod h1:wxt2YWRVItDtaQmVSmaN5ubE2L1c9CiNoHQwSJnM8Ko= +github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.7.7 h1:z4P744DR+PIpkjwXSEc6TvN3L6LVzmUquFgmNm8wSUc= +github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.7.7/go.mod h1:CM7HAH5PNuIsqjMN0fGc1ydM74Uj+0VZFhob620nklw= github.com/k8snetworkplumbingwg/sriovnet v1.2.1-0.20230427090635-4929697df2dc h1:v6+jUd70AayPbIRgTYUNpnBLG5cBPTY0+10y80CZeMk= github.com/k8snetworkplumbingwg/sriovnet v1.2.1-0.20230427090635-4929697df2dc/go.mod h1:jyWzGe6ZtYiPq6ih6aXCOy6mZ49Y9mNyBOLBBXnli+k= github.com/karrick/godirwalk v1.17.0 h1:b4kY7nqDdioR/6qnbHQyDvmA17u5G1cZ6J+CZXwSWoI= @@ -413,7 +415,6 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg= github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= From fa7558fc9c822bd3dce4c4d7c2290bfc6022c0a8 Mon Sep 17 00:00:00 2001 From: Enrique Llorente Date: Tue, 1 Jul 2025 09:43:58 +0200 Subject: [PATCH 029/115] go, deps: Pin CNI library to v1.2.3 to prevent OVN-K parsing issues Pin the 'containernetworking/cni' library dependency to v1.2.3. Version 1.3.0 introduced a breaking change where a new MarshalJSON function in the CNI library causes it to ignore custom OVN-K fields within 'nad.spec.config', leading to parsing failures. Signed-off-by: Enrique Llorente --- go-controller/go.mod | 3 +- go-controller/go.sum | 6 +- .../Masterminds/semver/v3/.gitignore | 1 - .../Masterminds/semver/v3/.golangci.yml | 27 - .../Masterminds/semver/v3/CHANGELOG.md | 214 ------ .../Masterminds/semver/v3/LICENSE.txt | 19 - .../github.com/Masterminds/semver/v3/Makefile | 30 - .../Masterminds/semver/v3/README.md | 258 ------- .../Masterminds/semver/v3/SECURITY.md | 19 - .../Masterminds/semver/v3/collection.go | 24 - .../Masterminds/semver/v3/constraints.go | 594 ---------------- .../github.com/Masterminds/semver/v3/doc.go | 184 ----- .../Masterminds/semver/v3/version.go | 639 ------------------ .../containernetworking/cni/libcni/api.go | 38 +- .../containernetworking/cni/libcni/conf.go | 79 ++- .../cni/libcni/multierror.go | 58 -- .../cni/pkg/ns/ns_darwin.go | 21 + .../cni/pkg/types/types.go | 12 +- .../cni/pkg/version/plugin.go | 24 + go-controller/vendor/modules.txt | 7 +- test/e2e/go.mod | 3 +- test/e2e/go.sum | 6 +- 22 files changed, 138 insertions(+), 2128 deletions(-) delete mode 100644 go-controller/vendor/github.com/Masterminds/semver/v3/.gitignore delete mode 100644 go-controller/vendor/github.com/Masterminds/semver/v3/.golangci.yml delete mode 100644 go-controller/vendor/github.com/Masterminds/semver/v3/CHANGELOG.md delete mode 100644 go-controller/vendor/github.com/Masterminds/semver/v3/LICENSE.txt delete mode 100644 go-controller/vendor/github.com/Masterminds/semver/v3/Makefile delete mode 100644 go-controller/vendor/github.com/Masterminds/semver/v3/README.md delete mode 100644 go-controller/vendor/github.com/Masterminds/semver/v3/SECURITY.md delete mode 100644 go-controller/vendor/github.com/Masterminds/semver/v3/collection.go delete mode 100644 go-controller/vendor/github.com/Masterminds/semver/v3/constraints.go delete mode 100644 go-controller/vendor/github.com/Masterminds/semver/v3/doc.go delete mode 100644 go-controller/vendor/github.com/Masterminds/semver/v3/version.go delete mode 100644 go-controller/vendor/github.com/containernetworking/cni/libcni/multierror.go create mode 100644 go-controller/vendor/github.com/containernetworking/cni/pkg/ns/ns_darwin.go diff --git a/go-controller/go.mod b/go-controller/go.mod index afd8cdfe11..0a4e54196b 100644 --- a/go-controller/go.mod +++ b/go-controller/go.mod @@ -10,7 +10,7 @@ require ( github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d github.com/bhendo/go-powershell v0.0.0-20190719160123-219e7fb4e41e github.com/cenkalti/backoff/v4 v4.3.0 - github.com/containernetworking/cni v1.2.0-rc1 + github.com/containernetworking/cni v1.2.3 github.com/containernetworking/plugins v1.2.0 github.com/coreos/go-iptables v0.6.0 github.com/fsnotify/fsnotify v1.7.0 @@ -73,7 +73,6 @@ require ( ) require ( - github.com/Masterminds/semver/v3 v3.2.1 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cenkalti/hub v1.0.1 // indirect diff --git a/go-controller/go.sum b/go-controller/go.sum index 6d72aee42e..d0bde9c817 100644 --- a/go-controller/go.sum +++ b/go-controller/go.sum @@ -55,8 +55,6 @@ github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBp github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/JacobTanenbaum/arping v0.0.0-20240209152419-3987db83bd51/go.mod h1:aJbELhR92bSk7tp79AWM/ftfc90EfEi2bQJrbBFOsPw= -github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= -github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.4.16-0.20201130162521-d1ffc52c7331/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= @@ -201,8 +199,8 @@ github.com/containerd/zfs v1.0.0/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNR github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= github.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= -github.com/containernetworking/cni v1.2.0-rc1 h1:AKI3+pXtgY4PDLN9+50o9IaywWVuey0Jkw3Lvzp0HCY= -github.com/containernetworking/cni v1.2.0-rc1/go.mod h1:Lt0TQcZQVDju64fYxUhDziTgXCDe3Olzi9I4zZJLWHg= +github.com/containernetworking/cni v1.2.3 h1:hhOcjNVUQTnzdRJ6alC5XF+wd9mfGIUaj8FuJbEslXM= +github.com/containernetworking/cni v1.2.3/go.mod h1:DuLgF+aPd3DzcTQTtp/Nvl1Kim23oFKdm2okJzBQA5M= github.com/containernetworking/plugins v0.8.6/go.mod h1:qnw5mN19D8fIwkqW7oHHYDHVlzhJpcY6TQxn/fUyDDM= github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8= github.com/containernetworking/plugins v1.2.0 h1:SWgg3dQG1yzUo4d9iD8cwSVh1VqI+bP7mkPDoSfP9VU= diff --git a/go-controller/vendor/github.com/Masterminds/semver/v3/.gitignore b/go-controller/vendor/github.com/Masterminds/semver/v3/.gitignore deleted file mode 100644 index 6b061e6174..0000000000 --- a/go-controller/vendor/github.com/Masterminds/semver/v3/.gitignore +++ /dev/null @@ -1 +0,0 @@ -_fuzz/ \ No newline at end of file diff --git a/go-controller/vendor/github.com/Masterminds/semver/v3/.golangci.yml b/go-controller/vendor/github.com/Masterminds/semver/v3/.golangci.yml deleted file mode 100644 index fbc6332592..0000000000 --- a/go-controller/vendor/github.com/Masterminds/semver/v3/.golangci.yml +++ /dev/null @@ -1,27 +0,0 @@ -run: - deadline: 2m - -linters: - disable-all: true - enable: - - misspell - - govet - - staticcheck - - errcheck - - unparam - - ineffassign - - nakedret - - gocyclo - - dupl - - goimports - - revive - - gosec - - gosimple - - typecheck - - unused - -linters-settings: - gofmt: - simplify: true - dupl: - threshold: 600 diff --git a/go-controller/vendor/github.com/Masterminds/semver/v3/CHANGELOG.md b/go-controller/vendor/github.com/Masterminds/semver/v3/CHANGELOG.md deleted file mode 100644 index f12626423a..0000000000 --- a/go-controller/vendor/github.com/Masterminds/semver/v3/CHANGELOG.md +++ /dev/null @@ -1,214 +0,0 @@ -# Changelog - -## 3.2.0 (2022-11-28) - -### Added - -- #190: Added text marshaling and unmarshaling -- #167: Added JSON marshalling for constraints (thanks @SimonTheLeg) -- #173: Implement encoding.TextMarshaler and encoding.TextUnmarshaler on Version (thanks @MarkRosemaker) -- #179: Added New() version constructor (thanks @kazhuravlev) - -### Changed - -- #182/#183: Updated CI testing setup - -### Fixed - -- #186: Fixing issue where validation of constraint section gave false positives -- #176: Fix constraints check with *-0 (thanks @mtt0) -- #181: Fixed Caret operator (^) gives unexpected results when the minor version in constraint is 0 (thanks @arshchimni) -- #161: Fixed godoc (thanks @afirth) - -## 3.1.1 (2020-11-23) - -### Fixed - -- #158: Fixed issue with generated regex operation order that could cause problem - -## 3.1.0 (2020-04-15) - -### Added - -- #131: Add support for serializing/deserializing SQL (thanks @ryancurrah) - -### Changed - -- #148: More accurate validation messages on constraints - -## 3.0.3 (2019-12-13) - -### Fixed - -- #141: Fixed issue with <= comparison - -## 3.0.2 (2019-11-14) - -### Fixed - -- #134: Fixed broken constraint checking with ^0.0 (thanks @krmichelos) - -## 3.0.1 (2019-09-13) - -### Fixed - -- #125: Fixes issue with module path for v3 - -## 3.0.0 (2019-09-12) - -This is a major release of the semver package which includes API changes. The Go -API is compatible with ^1. The Go API was not changed because many people are using -`go get` without Go modules for their applications and API breaking changes cause -errors which we have or would need to support. - -The changes in this release are the handling based on the data passed into the -functions. These are described in the added and changed sections below. - -### Added - -- StrictNewVersion function. This is similar to NewVersion but will return an - error if the version passed in is not a strict semantic version. For example, - 1.2.3 would pass but v1.2.3 or 1.2 would fail because they are not strictly - speaking semantic versions. This function is faster, performs fewer operations, - and uses fewer allocations than NewVersion. -- Fuzzing has been performed on NewVersion, StrictNewVersion, and NewConstraint. - The Makefile contains the operations used. For more information on you can start - on Wikipedia at https://en.wikipedia.org/wiki/Fuzzing -- Now using Go modules - -### Changed - -- NewVersion has proper prerelease and metadata validation with error messages - to signal an issue with either of them -- ^ now operates using a similar set of rules to npm/js and Rust/Cargo. If the - version is >=1 the ^ ranges works the same as v1. For major versions of 0 the - rules have changed. The minor version is treated as the stable version unless - a patch is specified and then it is equivalent to =. One difference from npm/js - is that prereleases there are only to a specific version (e.g. 1.2.3). - Prereleases here look over multiple versions and follow semantic version - ordering rules. This pattern now follows along with the expected and requested - handling of this packaged by numerous users. - -## 1.5.0 (2019-09-11) - -### Added - -- #103: Add basic fuzzing for `NewVersion()` (thanks @jesse-c) - -### Changed - -- #82: Clarify wildcard meaning in range constraints and update tests for it (thanks @greysteil) -- #83: Clarify caret operator range for pre-1.0.0 dependencies (thanks @greysteil) -- #72: Adding docs comment pointing to vert for a cli -- #71: Update the docs on pre-release comparator handling -- #89: Test with new go versions (thanks @thedevsaddam) -- #87: Added $ to ValidPrerelease for better validation (thanks @jeremycarroll) - -### Fixed - -- #78: Fix unchecked error in example code (thanks @ravron) -- #70: Fix the handling of pre-releases and the 0.0.0 release edge case -- #97: Fixed copyright file for proper display on GitHub -- #107: Fix handling prerelease when sorting alphanum and num -- #109: Fixed where Validate sometimes returns wrong message on error - -## 1.4.2 (2018-04-10) - -### Changed - -- #72: Updated the docs to point to vert for a console appliaction -- #71: Update the docs on pre-release comparator handling - -### Fixed - -- #70: Fix the handling of pre-releases and the 0.0.0 release edge case - -## 1.4.1 (2018-04-02) - -### Fixed - -- Fixed #64: Fix pre-release precedence issue (thanks @uudashr) - -## 1.4.0 (2017-10-04) - -### Changed - -- #61: Update NewVersion to parse ints with a 64bit int size (thanks @zknill) - -## 1.3.1 (2017-07-10) - -### Fixed - -- Fixed #57: number comparisons in prerelease sometimes inaccurate - -## 1.3.0 (2017-05-02) - -### Added - -- #45: Added json (un)marshaling support (thanks @mh-cbon) -- Stability marker. See https://masterminds.github.io/stability/ - -### Fixed - -- #51: Fix handling of single digit tilde constraint (thanks @dgodd) - -### Changed - -- #55: The godoc icon moved from png to svg - -## 1.2.3 (2017-04-03) - -### Fixed - -- #46: Fixed 0.x.x and 0.0.x in constraints being treated as * - -## Release 1.2.2 (2016-12-13) - -### Fixed - -- #34: Fixed issue where hyphen range was not working with pre-release parsing. - -## Release 1.2.1 (2016-11-28) - -### Fixed - -- #24: Fixed edge case issue where constraint "> 0" does not handle "0.0.1-alpha" - properly. - -## Release 1.2.0 (2016-11-04) - -### Added - -- #20: Added MustParse function for versions (thanks @adamreese) -- #15: Added increment methods on versions (thanks @mh-cbon) - -### Fixed - -- Issue #21: Per the SemVer spec (section 9) a pre-release is unstable and - might not satisfy the intended compatibility. The change here ignores pre-releases - on constraint checks (e.g., ~ or ^) when a pre-release is not part of the - constraint. For example, `^1.2.3` will ignore pre-releases while - `^1.2.3-alpha` will include them. - -## Release 1.1.1 (2016-06-30) - -### Changed - -- Issue #9: Speed up version comparison performance (thanks @sdboyer) -- Issue #8: Added benchmarks (thanks @sdboyer) -- Updated Go Report Card URL to new location -- Updated Readme to add code snippet formatting (thanks @mh-cbon) -- Updating tagging to v[SemVer] structure for compatibility with other tools. - -## Release 1.1.0 (2016-03-11) - -- Issue #2: Implemented validation to provide reasons a versions failed a - constraint. - -## Release 1.0.1 (2015-12-31) - -- Fixed #1: * constraint failing on valid versions. - -## Release 1.0.0 (2015-10-20) - -- Initial release diff --git a/go-controller/vendor/github.com/Masterminds/semver/v3/LICENSE.txt b/go-controller/vendor/github.com/Masterminds/semver/v3/LICENSE.txt deleted file mode 100644 index 9ff7da9c48..0000000000 --- a/go-controller/vendor/github.com/Masterminds/semver/v3/LICENSE.txt +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (C) 2014-2019, Matt Butcher and Matt Farina - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/go-controller/vendor/github.com/Masterminds/semver/v3/Makefile b/go-controller/vendor/github.com/Masterminds/semver/v3/Makefile deleted file mode 100644 index 0e7b5c7138..0000000000 --- a/go-controller/vendor/github.com/Masterminds/semver/v3/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -GOPATH=$(shell go env GOPATH) -GOLANGCI_LINT=$(GOPATH)/bin/golangci-lint - -.PHONY: lint -lint: $(GOLANGCI_LINT) - @echo "==> Linting codebase" - @$(GOLANGCI_LINT) run - -.PHONY: test -test: - @echo "==> Running tests" - GO111MODULE=on go test -v - -.PHONY: test-cover -test-cover: - @echo "==> Running Tests with coverage" - GO111MODULE=on go test -cover . - -.PHONY: fuzz -fuzz: - @echo "==> Running Fuzz Tests" - go test -fuzz=FuzzNewVersion -fuzztime=15s . - go test -fuzz=FuzzStrictNewVersion -fuzztime=15s . - go test -fuzz=FuzzNewConstraint -fuzztime=15s . - -$(GOLANGCI_LINT): - # Install golangci-lint. The configuration for it is in the .golangci.yml - # file in the root of the repository - echo ${GOPATH} - curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(GOPATH)/bin v1.17.1 diff --git a/go-controller/vendor/github.com/Masterminds/semver/v3/README.md b/go-controller/vendor/github.com/Masterminds/semver/v3/README.md deleted file mode 100644 index eab8cac3b7..0000000000 --- a/go-controller/vendor/github.com/Masterminds/semver/v3/README.md +++ /dev/null @@ -1,258 +0,0 @@ -# SemVer - -The `semver` package provides the ability to work with [Semantic Versions](http://semver.org) in Go. Specifically it provides the ability to: - -* Parse semantic versions -* Sort semantic versions -* Check if a semantic version fits within a set of constraints -* Optionally work with a `v` prefix - -[![Stability: -Active](https://masterminds.github.io/stability/active.svg)](https://masterminds.github.io/stability/active.html) -[![](https://github.com/Masterminds/semver/workflows/Tests/badge.svg)](https://github.com/Masterminds/semver/actions) -[![GoDoc](https://img.shields.io/static/v1?label=godoc&message=reference&color=blue)](https://pkg.go.dev/github.com/Masterminds/semver/v3) -[![Go Report Card](https://goreportcard.com/badge/github.com/Masterminds/semver)](https://goreportcard.com/report/github.com/Masterminds/semver) - -If you are looking for a command line tool for version comparisons please see -[vert](https://github.com/Masterminds/vert) which uses this library. - -## Package Versions - -Note, import `github.com/github.com/Masterminds/semver/v3` to use the latest version. - -There are three major versions fo the `semver` package. - -* 3.x.x is the stable and active version. This version is focused on constraint - compatibility for range handling in other tools from other languages. It has - a similar API to the v1 releases. The development of this version is on the master - branch. The documentation for this version is below. -* 2.x was developed primarily for [dep](https://github.com/golang/dep). There are - no tagged releases and the development was performed by [@sdboyer](https://github.com/sdboyer). - There are API breaking changes from v1. This version lives on the [2.x branch](https://github.com/Masterminds/semver/tree/2.x). -* 1.x.x is the original release. It is no longer maintained. You should use the - v3 release instead. You can read the documentation for the 1.x.x release - [here](https://github.com/Masterminds/semver/blob/release-1/README.md). - -## Parsing Semantic Versions - -There are two functions that can parse semantic versions. The `StrictNewVersion` -function only parses valid version 2 semantic versions as outlined in the -specification. The `NewVersion` function attempts to coerce a version into a -semantic version and parse it. For example, if there is a leading v or a version -listed without all 3 parts (e.g. `v1.2`) it will attempt to coerce it into a valid -semantic version (e.g., 1.2.0). In both cases a `Version` object is returned -that can be sorted, compared, and used in constraints. - -When parsing a version an error is returned if there is an issue parsing the -version. For example, - - v, err := semver.NewVersion("1.2.3-beta.1+build345") - -The version object has methods to get the parts of the version, compare it to -other versions, convert the version back into a string, and get the original -string. Getting the original string is useful if the semantic version was coerced -into a valid form. - -## Sorting Semantic Versions - -A set of versions can be sorted using the `sort` package from the standard library. -For example, - -```go -raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",} -vs := make([]*semver.Version, len(raw)) -for i, r := range raw { - v, err := semver.NewVersion(r) - if err != nil { - t.Errorf("Error parsing version: %s", err) - } - - vs[i] = v -} - -sort.Sort(semver.Collection(vs)) -``` - -## Checking Version Constraints - -There are two methods for comparing versions. One uses comparison methods on -`Version` instances and the other uses `Constraints`. There are some important -differences to notes between these two methods of comparison. - -1. When two versions are compared using functions such as `Compare`, `LessThan`, - and others it will follow the specification and always include prereleases - within the comparison. It will provide an answer that is valid with the - comparison section of the spec at https://semver.org/#spec-item-11 -2. When constraint checking is used for checks or validation it will follow a - different set of rules that are common for ranges with tools like npm/js - and Rust/Cargo. This includes considering prereleases to be invalid if the - ranges does not include one. If you want to have it include pre-releases a - simple solution is to include `-0` in your range. -3. Constraint ranges can have some complex rules including the shorthand use of - ~ and ^. For more details on those see the options below. - -There are differences between the two methods or checking versions because the -comparison methods on `Version` follow the specification while comparison ranges -are not part of the specification. Different packages and tools have taken it -upon themselves to come up with range rules. This has resulted in differences. -For example, npm/js and Cargo/Rust follow similar patterns while PHP has a -different pattern for ^. The comparison features in this package follow the -npm/js and Cargo/Rust lead because applications using it have followed similar -patters with their versions. - -Checking a version against version constraints is one of the most featureful -parts of the package. - -```go -c, err := semver.NewConstraint(">= 1.2.3") -if err != nil { - // Handle constraint not being parsable. -} - -v, err := semver.NewVersion("1.3") -if err != nil { - // Handle version not being parsable. -} -// Check if the version meets the constraints. The a variable will be true. -a := c.Check(v) -``` - -### Basic Comparisons - -There are two elements to the comparisons. First, a comparison string is a list -of space or comma separated AND comparisons. These are then separated by || (OR) -comparisons. For example, `">= 1.2 < 3.0.0 || >= 4.2.3"` is looking for a -comparison that's greater than or equal to 1.2 and less than 3.0.0 or is -greater than or equal to 4.2.3. - -The basic comparisons are: - -* `=`: equal (aliased to no operator) -* `!=`: not equal -* `>`: greater than -* `<`: less than -* `>=`: greater than or equal to -* `<=`: less than or equal to - -### Working With Prerelease Versions - -Pre-releases, for those not familiar with them, are used for software releases -prior to stable or generally available releases. Examples of prereleases include -development, alpha, beta, and release candidate releases. A prerelease may be -a version such as `1.2.3-beta.1` while the stable release would be `1.2.3`. In the -order of precedence, prereleases come before their associated releases. In this -example `1.2.3-beta.1 < 1.2.3`. - -According to the Semantic Version specification prereleases may not be -API compliant with their release counterpart. It says, - -> A pre-release version indicates that the version is unstable and might not satisfy the intended compatibility requirements as denoted by its associated normal version. - -SemVer comparisons using constraints without a prerelease comparator will skip -prerelease versions. For example, `>=1.2.3` will skip prereleases when looking -at a list of releases while `>=1.2.3-0` will evaluate and find prereleases. - -The reason for the `0` as a pre-release version in the example comparison is -because pre-releases can only contain ASCII alphanumerics and hyphens (along with -`.` separators), per the spec. Sorting happens in ASCII sort order, again per the -spec. The lowest character is a `0` in ASCII sort order -(see an [ASCII Table](http://www.asciitable.com/)) - -Understanding ASCII sort ordering is important because A-Z comes before a-z. That -means `>=1.2.3-BETA` will return `1.2.3-alpha`. What you might expect from case -sensitivity doesn't apply here. This is due to ASCII sort ordering which is what -the spec specifies. - -### Hyphen Range Comparisons - -There are multiple methods to handle ranges and the first is hyphens ranges. -These look like: - -* `1.2 - 1.4.5` which is equivalent to `>= 1.2 <= 1.4.5` -* `2.3.4 - 4.5` which is equivalent to `>= 2.3.4 <= 4.5` - -### Wildcards In Comparisons - -The `x`, `X`, and `*` characters can be used as a wildcard character. This works -for all comparison operators. When used on the `=` operator it falls -back to the patch level comparison (see tilde below). For example, - -* `1.2.x` is equivalent to `>= 1.2.0, < 1.3.0` -* `>= 1.2.x` is equivalent to `>= 1.2.0` -* `<= 2.x` is equivalent to `< 3` -* `*` is equivalent to `>= 0.0.0` - -### Tilde Range Comparisons (Patch) - -The tilde (`~`) comparison operator is for patch level ranges when a minor -version is specified and major level changes when the minor number is missing. -For example, - -* `~1.2.3` is equivalent to `>= 1.2.3, < 1.3.0` -* `~1` is equivalent to `>= 1, < 2` -* `~2.3` is equivalent to `>= 2.3, < 2.4` -* `~1.2.x` is equivalent to `>= 1.2.0, < 1.3.0` -* `~1.x` is equivalent to `>= 1, < 2` - -### Caret Range Comparisons (Major) - -The caret (`^`) comparison operator is for major level changes once a stable -(1.0.0) release has occurred. Prior to a 1.0.0 release the minor versions acts -as the API stability level. This is useful when comparisons of API versions as a -major change is API breaking. For example, - -* `^1.2.3` is equivalent to `>= 1.2.3, < 2.0.0` -* `^1.2.x` is equivalent to `>= 1.2.0, < 2.0.0` -* `^2.3` is equivalent to `>= 2.3, < 3` -* `^2.x` is equivalent to `>= 2.0.0, < 3` -* `^0.2.3` is equivalent to `>=0.2.3 <0.3.0` -* `^0.2` is equivalent to `>=0.2.0 <0.3.0` -* `^0.0.3` is equivalent to `>=0.0.3 <0.0.4` -* `^0.0` is equivalent to `>=0.0.0 <0.1.0` -* `^0` is equivalent to `>=0.0.0 <1.0.0` - -## Validation - -In addition to testing a version against a constraint, a version can be validated -against a constraint. When validation fails a slice of errors containing why a -version didn't meet the constraint is returned. For example, - -```go -c, err := semver.NewConstraint("<= 1.2.3, >= 1.4") -if err != nil { - // Handle constraint not being parseable. -} - -v, err := semver.NewVersion("1.3") -if err != nil { - // Handle version not being parseable. -} - -// Validate a version against a constraint. -a, msgs := c.Validate(v) -// a is false -for _, m := range msgs { - fmt.Println(m) - - // Loops over the errors which would read - // "1.3 is greater than 1.2.3" - // "1.3 is less than 1.4" -} -``` - -## Contribute - -If you find an issue or want to contribute please file an [issue](https://github.com/Masterminds/semver/issues) -or [create a pull request](https://github.com/Masterminds/semver/pulls). - -## Security - -Security is an important consideration for this project. The project currently -uses the following tools to help discover security issues: - -* [CodeQL](https://github.com/Masterminds/semver) -* [gosec](https://github.com/securego/gosec) -* Daily Fuzz testing - -If you believe you have found a security vulnerability you can privately disclose -it through the [GitHub security page](https://github.com/Masterminds/semver/security). diff --git a/go-controller/vendor/github.com/Masterminds/semver/v3/SECURITY.md b/go-controller/vendor/github.com/Masterminds/semver/v3/SECURITY.md deleted file mode 100644 index a30a66b1f7..0000000000 --- a/go-controller/vendor/github.com/Masterminds/semver/v3/SECURITY.md +++ /dev/null @@ -1,19 +0,0 @@ -# Security Policy - -## Supported Versions - -The following versions of semver are currently supported: - -| Version | Supported | -| ------- | ------------------ | -| 3.x | :white_check_mark: | -| 2.x | :x: | -| 1.x | :x: | - -Fixes are only released for the latest minor version in the form of a patch release. - -## Reporting a Vulnerability - -You can privately disclose a vulnerability through GitHubs -[private vulnerability reporting](https://github.com/Masterminds/semver/security/advisories) -mechanism. diff --git a/go-controller/vendor/github.com/Masterminds/semver/v3/collection.go b/go-controller/vendor/github.com/Masterminds/semver/v3/collection.go deleted file mode 100644 index a78235895f..0000000000 --- a/go-controller/vendor/github.com/Masterminds/semver/v3/collection.go +++ /dev/null @@ -1,24 +0,0 @@ -package semver - -// Collection is a collection of Version instances and implements the sort -// interface. See the sort package for more details. -// https://golang.org/pkg/sort/ -type Collection []*Version - -// Len returns the length of a collection. The number of Version instances -// on the slice. -func (c Collection) Len() int { - return len(c) -} - -// Less is needed for the sort interface to compare two Version objects on the -// slice. If checks if one is less than the other. -func (c Collection) Less(i, j int) bool { - return c[i].LessThan(c[j]) -} - -// Swap is needed for the sort interface to replace the Version objects -// at two different positions in the slice. -func (c Collection) Swap(i, j int) { - c[i], c[j] = c[j], c[i] -} diff --git a/go-controller/vendor/github.com/Masterminds/semver/v3/constraints.go b/go-controller/vendor/github.com/Masterminds/semver/v3/constraints.go deleted file mode 100644 index 8461c7ed90..0000000000 --- a/go-controller/vendor/github.com/Masterminds/semver/v3/constraints.go +++ /dev/null @@ -1,594 +0,0 @@ -package semver - -import ( - "bytes" - "errors" - "fmt" - "regexp" - "strings" -) - -// Constraints is one or more constraint that a semantic version can be -// checked against. -type Constraints struct { - constraints [][]*constraint -} - -// NewConstraint returns a Constraints instance that a Version instance can -// be checked against. If there is a parse error it will be returned. -func NewConstraint(c string) (*Constraints, error) { - - // Rewrite - ranges into a comparison operation. - c = rewriteRange(c) - - ors := strings.Split(c, "||") - or := make([][]*constraint, len(ors)) - for k, v := range ors { - - // TODO: Find a way to validate and fetch all the constraints in a simpler form - - // Validate the segment - if !validConstraintRegex.MatchString(v) { - return nil, fmt.Errorf("improper constraint: %s", v) - } - - cs := findConstraintRegex.FindAllString(v, -1) - if cs == nil { - cs = append(cs, v) - } - result := make([]*constraint, len(cs)) - for i, s := range cs { - pc, err := parseConstraint(s) - if err != nil { - return nil, err - } - - result[i] = pc - } - or[k] = result - } - - o := &Constraints{constraints: or} - return o, nil -} - -// Check tests if a version satisfies the constraints. -func (cs Constraints) Check(v *Version) bool { - // TODO(mattfarina): For v4 of this library consolidate the Check and Validate - // functions as the underlying functions make that possible now. - // loop over the ORs and check the inner ANDs - for _, o := range cs.constraints { - joy := true - for _, c := range o { - if check, _ := c.check(v); !check { - joy = false - break - } - } - - if joy { - return true - } - } - - return false -} - -// Validate checks if a version satisfies a constraint. If not a slice of -// reasons for the failure are returned in addition to a bool. -func (cs Constraints) Validate(v *Version) (bool, []error) { - // loop over the ORs and check the inner ANDs - var e []error - - // Capture the prerelease message only once. When it happens the first time - // this var is marked - var prerelesase bool - for _, o := range cs.constraints { - joy := true - for _, c := range o { - // Before running the check handle the case there the version is - // a prerelease and the check is not searching for prereleases. - if c.con.pre == "" && v.pre != "" { - if !prerelesase { - em := fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) - e = append(e, em) - prerelesase = true - } - joy = false - - } else { - - if _, err := c.check(v); err != nil { - e = append(e, err) - joy = false - } - } - } - - if joy { - return true, []error{} - } - } - - return false, e -} - -func (cs Constraints) String() string { - buf := make([]string, len(cs.constraints)) - var tmp bytes.Buffer - - for k, v := range cs.constraints { - tmp.Reset() - vlen := len(v) - for kk, c := range v { - tmp.WriteString(c.string()) - - // Space separate the AND conditions - if vlen > 1 && kk < vlen-1 { - tmp.WriteString(" ") - } - } - buf[k] = tmp.String() - } - - return strings.Join(buf, " || ") -} - -// UnmarshalText implements the encoding.TextUnmarshaler interface. -func (cs *Constraints) UnmarshalText(text []byte) error { - temp, err := NewConstraint(string(text)) - if err != nil { - return err - } - - *cs = *temp - - return nil -} - -// MarshalText implements the encoding.TextMarshaler interface. -func (cs Constraints) MarshalText() ([]byte, error) { - return []byte(cs.String()), nil -} - -var constraintOps map[string]cfunc -var constraintRegex *regexp.Regexp -var constraintRangeRegex *regexp.Regexp - -// Used to find individual constraints within a multi-constraint string -var findConstraintRegex *regexp.Regexp - -// Used to validate an segment of ANDs is valid -var validConstraintRegex *regexp.Regexp - -const cvRegex string = `v?([0-9|x|X|\*]+)(\.[0-9|x|X|\*]+)?(\.[0-9|x|X|\*]+)?` + - `(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` + - `(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` - -func init() { - constraintOps = map[string]cfunc{ - "": constraintTildeOrEqual, - "=": constraintTildeOrEqual, - "!=": constraintNotEqual, - ">": constraintGreaterThan, - "<": constraintLessThan, - ">=": constraintGreaterThanEqual, - "=>": constraintGreaterThanEqual, - "<=": constraintLessThanEqual, - "=<": constraintLessThanEqual, - "~": constraintTilde, - "~>": constraintTilde, - "^": constraintCaret, - } - - ops := `=||!=|>|<|>=|=>|<=|=<|~|~>|\^` - - constraintRegex = regexp.MustCompile(fmt.Sprintf( - `^\s*(%s)\s*(%s)\s*$`, - ops, - cvRegex)) - - constraintRangeRegex = regexp.MustCompile(fmt.Sprintf( - `\s*(%s)\s+-\s+(%s)\s*`, - cvRegex, cvRegex)) - - findConstraintRegex = regexp.MustCompile(fmt.Sprintf( - `(%s)\s*(%s)`, - ops, - cvRegex)) - - // The first time a constraint shows up will look slightly different from - // future times it shows up due to a leading space or comma in a given - // string. - validConstraintRegex = regexp.MustCompile(fmt.Sprintf( - `^(\s*(%s)\s*(%s)\s*)((?:\s+|,\s*)(%s)\s*(%s)\s*)*$`, - ops, - cvRegex, - ops, - cvRegex)) -} - -// An individual constraint -type constraint struct { - // The version used in the constraint check. For example, if a constraint - // is '<= 2.0.0' the con a version instance representing 2.0.0. - con *Version - - // The original parsed version (e.g., 4.x from != 4.x) - orig string - - // The original operator for the constraint - origfunc string - - // When an x is used as part of the version (e.g., 1.x) - minorDirty bool - dirty bool - patchDirty bool -} - -// Check if a version meets the constraint -func (c *constraint) check(v *Version) (bool, error) { - return constraintOps[c.origfunc](v, c) -} - -// String prints an individual constraint into a string -func (c *constraint) string() string { - return c.origfunc + c.orig -} - -type cfunc func(v *Version, c *constraint) (bool, error) - -func parseConstraint(c string) (*constraint, error) { - if len(c) > 0 { - m := constraintRegex.FindStringSubmatch(c) - if m == nil { - return nil, fmt.Errorf("improper constraint: %s", c) - } - - cs := &constraint{ - orig: m[2], - origfunc: m[1], - } - - ver := m[2] - minorDirty := false - patchDirty := false - dirty := false - if isX(m[3]) || m[3] == "" { - ver = fmt.Sprintf("0.0.0%s", m[6]) - dirty = true - } else if isX(strings.TrimPrefix(m[4], ".")) || m[4] == "" { - minorDirty = true - dirty = true - ver = fmt.Sprintf("%s.0.0%s", m[3], m[6]) - } else if isX(strings.TrimPrefix(m[5], ".")) || m[5] == "" { - dirty = true - patchDirty = true - ver = fmt.Sprintf("%s%s.0%s", m[3], m[4], m[6]) - } - - con, err := NewVersion(ver) - if err != nil { - - // The constraintRegex should catch any regex parsing errors. So, - // we should never get here. - return nil, errors.New("constraint Parser Error") - } - - cs.con = con - cs.minorDirty = minorDirty - cs.patchDirty = patchDirty - cs.dirty = dirty - - return cs, nil - } - - // The rest is the special case where an empty string was passed in which - // is equivalent to * or >=0.0.0 - con, err := StrictNewVersion("0.0.0") - if err != nil { - - // The constraintRegex should catch any regex parsing errors. So, - // we should never get here. - return nil, errors.New("constraint Parser Error") - } - - cs := &constraint{ - con: con, - orig: c, - origfunc: "", - minorDirty: false, - patchDirty: false, - dirty: true, - } - return cs, nil -} - -// Constraint functions -func constraintNotEqual(v *Version, c *constraint) (bool, error) { - if c.dirty { - - // If there is a pre-release on the version but the constraint isn't looking - // for them assume that pre-releases are not compatible. See issue 21 for - // more details. - if v.Prerelease() != "" && c.con.Prerelease() == "" { - return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) - } - - if c.con.Major() != v.Major() { - return true, nil - } - if c.con.Minor() != v.Minor() && !c.minorDirty { - return true, nil - } else if c.minorDirty { - return false, fmt.Errorf("%s is equal to %s", v, c.orig) - } else if c.con.Patch() != v.Patch() && !c.patchDirty { - return true, nil - } else if c.patchDirty { - // Need to handle prereleases if present - if v.Prerelease() != "" || c.con.Prerelease() != "" { - eq := comparePrerelease(v.Prerelease(), c.con.Prerelease()) != 0 - if eq { - return true, nil - } - return false, fmt.Errorf("%s is equal to %s", v, c.orig) - } - return false, fmt.Errorf("%s is equal to %s", v, c.orig) - } - } - - eq := v.Equal(c.con) - if eq { - return false, fmt.Errorf("%s is equal to %s", v, c.orig) - } - - return true, nil -} - -func constraintGreaterThan(v *Version, c *constraint) (bool, error) { - - // If there is a pre-release on the version but the constraint isn't looking - // for them assume that pre-releases are not compatible. See issue 21 for - // more details. - if v.Prerelease() != "" && c.con.Prerelease() == "" { - return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) - } - - var eq bool - - if !c.dirty { - eq = v.Compare(c.con) == 1 - if eq { - return true, nil - } - return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig) - } - - if v.Major() > c.con.Major() { - return true, nil - } else if v.Major() < c.con.Major() { - return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig) - } else if c.minorDirty { - // This is a range case such as >11. When the version is something like - // 11.1.0 is it not > 11. For that we would need 12 or higher - return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig) - } else if c.patchDirty { - // This is for ranges such as >11.1. A version of 11.1.1 is not greater - // which one of 11.2.1 is greater - eq = v.Minor() > c.con.Minor() - if eq { - return true, nil - } - return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig) - } - - // If we have gotten here we are not comparing pre-preleases and can use the - // Compare function to accomplish that. - eq = v.Compare(c.con) == 1 - if eq { - return true, nil - } - return false, fmt.Errorf("%s is less than or equal to %s", v, c.orig) -} - -func constraintLessThan(v *Version, c *constraint) (bool, error) { - // If there is a pre-release on the version but the constraint isn't looking - // for them assume that pre-releases are not compatible. See issue 21 for - // more details. - if v.Prerelease() != "" && c.con.Prerelease() == "" { - return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) - } - - eq := v.Compare(c.con) < 0 - if eq { - return true, nil - } - return false, fmt.Errorf("%s is greater than or equal to %s", v, c.orig) -} - -func constraintGreaterThanEqual(v *Version, c *constraint) (bool, error) { - - // If there is a pre-release on the version but the constraint isn't looking - // for them assume that pre-releases are not compatible. See issue 21 for - // more details. - if v.Prerelease() != "" && c.con.Prerelease() == "" { - return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) - } - - eq := v.Compare(c.con) >= 0 - if eq { - return true, nil - } - return false, fmt.Errorf("%s is less than %s", v, c.orig) -} - -func constraintLessThanEqual(v *Version, c *constraint) (bool, error) { - // If there is a pre-release on the version but the constraint isn't looking - // for them assume that pre-releases are not compatible. See issue 21 for - // more details. - if v.Prerelease() != "" && c.con.Prerelease() == "" { - return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) - } - - var eq bool - - if !c.dirty { - eq = v.Compare(c.con) <= 0 - if eq { - return true, nil - } - return false, fmt.Errorf("%s is greater than %s", v, c.orig) - } - - if v.Major() > c.con.Major() { - return false, fmt.Errorf("%s is greater than %s", v, c.orig) - } else if v.Major() == c.con.Major() && v.Minor() > c.con.Minor() && !c.minorDirty { - return false, fmt.Errorf("%s is greater than %s", v, c.orig) - } - - return true, nil -} - -// ~*, ~>* --> >= 0.0.0 (any) -// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0, <3.0.0 -// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0, <2.1.0 -// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0, <1.3.0 -// ~1.2.3, ~>1.2.3 --> >=1.2.3, <1.3.0 -// ~1.2.0, ~>1.2.0 --> >=1.2.0, <1.3.0 -func constraintTilde(v *Version, c *constraint) (bool, error) { - // If there is a pre-release on the version but the constraint isn't looking - // for them assume that pre-releases are not compatible. See issue 21 for - // more details. - if v.Prerelease() != "" && c.con.Prerelease() == "" { - return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) - } - - if v.LessThan(c.con) { - return false, fmt.Errorf("%s is less than %s", v, c.orig) - } - - // ~0.0.0 is a special case where all constraints are accepted. It's - // equivalent to >= 0.0.0. - if c.con.Major() == 0 && c.con.Minor() == 0 && c.con.Patch() == 0 && - !c.minorDirty && !c.patchDirty { - return true, nil - } - - if v.Major() != c.con.Major() { - return false, fmt.Errorf("%s does not have same major version as %s", v, c.orig) - } - - if v.Minor() != c.con.Minor() && !c.minorDirty { - return false, fmt.Errorf("%s does not have same major and minor version as %s", v, c.orig) - } - - return true, nil -} - -// When there is a .x (dirty) status it automatically opts in to ~. Otherwise -// it's a straight = -func constraintTildeOrEqual(v *Version, c *constraint) (bool, error) { - // If there is a pre-release on the version but the constraint isn't looking - // for them assume that pre-releases are not compatible. See issue 21 for - // more details. - if v.Prerelease() != "" && c.con.Prerelease() == "" { - return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) - } - - if c.dirty { - return constraintTilde(v, c) - } - - eq := v.Equal(c.con) - if eq { - return true, nil - } - - return false, fmt.Errorf("%s is not equal to %s", v, c.orig) -} - -// ^* --> (any) -// ^1.2.3 --> >=1.2.3 <2.0.0 -// ^1.2 --> >=1.2.0 <2.0.0 -// ^1 --> >=1.0.0 <2.0.0 -// ^0.2.3 --> >=0.2.3 <0.3.0 -// ^0.2 --> >=0.2.0 <0.3.0 -// ^0.0.3 --> >=0.0.3 <0.0.4 -// ^0.0 --> >=0.0.0 <0.1.0 -// ^0 --> >=0.0.0 <1.0.0 -func constraintCaret(v *Version, c *constraint) (bool, error) { - // If there is a pre-release on the version but the constraint isn't looking - // for them assume that pre-releases are not compatible. See issue 21 for - // more details. - if v.Prerelease() != "" && c.con.Prerelease() == "" { - return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v) - } - - // This less than handles prereleases - if v.LessThan(c.con) { - return false, fmt.Errorf("%s is less than %s", v, c.orig) - } - - var eq bool - - // ^ when the major > 0 is >=x.y.z < x+1 - if c.con.Major() > 0 || c.minorDirty { - - // ^ has to be within a major range for > 0. Everything less than was - // filtered out with the LessThan call above. This filters out those - // that greater but not within the same major range. - eq = v.Major() == c.con.Major() - if eq { - return true, nil - } - return false, fmt.Errorf("%s does not have same major version as %s", v, c.orig) - } - - // ^ when the major is 0 and minor > 0 is >=0.y.z < 0.y+1 - if c.con.Major() == 0 && v.Major() > 0 { - return false, fmt.Errorf("%s does not have same major version as %s", v, c.orig) - } - // If the con Minor is > 0 it is not dirty - if c.con.Minor() > 0 || c.patchDirty { - eq = v.Minor() == c.con.Minor() - if eq { - return true, nil - } - return false, fmt.Errorf("%s does not have same minor version as %s. Expected minor versions to match when constraint major version is 0", v, c.orig) - } - // ^ when the minor is 0 and minor > 0 is =0.0.z - if c.con.Minor() == 0 && v.Minor() > 0 { - return false, fmt.Errorf("%s does not have same minor version as %s", v, c.orig) - } - - // At this point the major is 0 and the minor is 0 and not dirty. The patch - // is not dirty so we need to check if they are equal. If they are not equal - eq = c.con.Patch() == v.Patch() - if eq { - return true, nil - } - return false, fmt.Errorf("%s does not equal %s. Expect version and constraint to equal when major and minor versions are 0", v, c.orig) -} - -func isX(x string) bool { - switch x { - case "x", "*", "X": - return true - default: - return false - } -} - -func rewriteRange(i string) string { - m := constraintRangeRegex.FindAllStringSubmatch(i, -1) - if m == nil { - return i - } - o := i - for _, v := range m { - t := fmt.Sprintf(">= %s, <= %s ", v[1], v[11]) - o = strings.Replace(o, v[0], t, 1) - } - - return o -} diff --git a/go-controller/vendor/github.com/Masterminds/semver/v3/doc.go b/go-controller/vendor/github.com/Masterminds/semver/v3/doc.go deleted file mode 100644 index 74f97caa57..0000000000 --- a/go-controller/vendor/github.com/Masterminds/semver/v3/doc.go +++ /dev/null @@ -1,184 +0,0 @@ -/* -Package semver provides the ability to work with Semantic Versions (http://semver.org) in Go. - -Specifically it provides the ability to: - - - Parse semantic versions - - Sort semantic versions - - Check if a semantic version fits within a set of constraints - - Optionally work with a `v` prefix - -# Parsing Semantic Versions - -There are two functions that can parse semantic versions. The `StrictNewVersion` -function only parses valid version 2 semantic versions as outlined in the -specification. The `NewVersion` function attempts to coerce a version into a -semantic version and parse it. For example, if there is a leading v or a version -listed without all 3 parts (e.g. 1.2) it will attempt to coerce it into a valid -semantic version (e.g., 1.2.0). In both cases a `Version` object is returned -that can be sorted, compared, and used in constraints. - -When parsing a version an optional error can be returned if there is an issue -parsing the version. For example, - - v, err := semver.NewVersion("1.2.3-beta.1+b345") - -The version object has methods to get the parts of the version, compare it to -other versions, convert the version back into a string, and get the original -string. For more details please see the documentation -at https://godoc.org/github.com/Masterminds/semver. - -# Sorting Semantic Versions - -A set of versions can be sorted using the `sort` package from the standard library. -For example, - - raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",} - vs := make([]*semver.Version, len(raw)) - for i, r := range raw { - v, err := semver.NewVersion(r) - if err != nil { - t.Errorf("Error parsing version: %s", err) - } - - vs[i] = v - } - - sort.Sort(semver.Collection(vs)) - -# Checking Version Constraints and Comparing Versions - -There are two methods for comparing versions. One uses comparison methods on -`Version` instances and the other is using Constraints. There are some important -differences to notes between these two methods of comparison. - - 1. When two versions are compared using functions such as `Compare`, `LessThan`, - and others it will follow the specification and always include prereleases - within the comparison. It will provide an answer valid with the comparison - spec section at https://semver.org/#spec-item-11 - 2. When constraint checking is used for checks or validation it will follow a - different set of rules that are common for ranges with tools like npm/js - and Rust/Cargo. This includes considering prereleases to be invalid if the - ranges does not include on. If you want to have it include pre-releases a - simple solution is to include `-0` in your range. - 3. Constraint ranges can have some complex rules including the shorthard use of - ~ and ^. For more details on those see the options below. - -There are differences between the two methods or checking versions because the -comparison methods on `Version` follow the specification while comparison ranges -are not part of the specification. Different packages and tools have taken it -upon themselves to come up with range rules. This has resulted in differences. -For example, npm/js and Cargo/Rust follow similar patterns which PHP has a -different pattern for ^. The comparison features in this package follow the -npm/js and Cargo/Rust lead because applications using it have followed similar -patters with their versions. - -Checking a version against version constraints is one of the most featureful -parts of the package. - - c, err := semver.NewConstraint(">= 1.2.3") - if err != nil { - // Handle constraint not being parsable. - } - - v, err := semver.NewVersion("1.3") - if err != nil { - // Handle version not being parsable. - } - // Check if the version meets the constraints. The a variable will be true. - a := c.Check(v) - -# Basic Comparisons - -There are two elements to the comparisons. First, a comparison string is a list -of comma or space separated AND comparisons. These are then separated by || (OR) -comparisons. For example, `">= 1.2 < 3.0.0 || >= 4.2.3"` is looking for a -comparison that's greater than or equal to 1.2 and less than 3.0.0 or is -greater than or equal to 4.2.3. This can also be written as -`">= 1.2, < 3.0.0 || >= 4.2.3"` - -The basic comparisons are: - - - `=`: equal (aliased to no operator) - - `!=`: not equal - - `>`: greater than - - `<`: less than - - `>=`: greater than or equal to - - `<=`: less than or equal to - -# Hyphen Range Comparisons - -There are multiple methods to handle ranges and the first is hyphens ranges. -These look like: - - - `1.2 - 1.4.5` which is equivalent to `>= 1.2, <= 1.4.5` - - `2.3.4 - 4.5` which is equivalent to `>= 2.3.4 <= 4.5` - -# Wildcards In Comparisons - -The `x`, `X`, and `*` characters can be used as a wildcard character. This works -for all comparison operators. When used on the `=` operator it falls -back to the tilde operation. For example, - - - `1.2.x` is equivalent to `>= 1.2.0 < 1.3.0` - - `>= 1.2.x` is equivalent to `>= 1.2.0` - - `<= 2.x` is equivalent to `<= 3` - - `*` is equivalent to `>= 0.0.0` - -Tilde Range Comparisons (Patch) - -The tilde (`~`) comparison operator is for patch level ranges when a minor -version is specified and major level changes when the minor number is missing. -For example, - - - `~1.2.3` is equivalent to `>= 1.2.3 < 1.3.0` - - `~1` is equivalent to `>= 1, < 2` - - `~2.3` is equivalent to `>= 2.3 < 2.4` - - `~1.2.x` is equivalent to `>= 1.2.0 < 1.3.0` - - `~1.x` is equivalent to `>= 1 < 2` - -Caret Range Comparisons (Major) - -The caret (`^`) comparison operator is for major level changes once a stable -(1.0.0) release has occurred. Prior to a 1.0.0 release the minor versions acts -as the API stability level. This is useful when comparisons of API versions as a -major change is API breaking. For example, - - - `^1.2.3` is equivalent to `>= 1.2.3, < 2.0.0` - - `^1.2.x` is equivalent to `>= 1.2.0, < 2.0.0` - - `^2.3` is equivalent to `>= 2.3, < 3` - - `^2.x` is equivalent to `>= 2.0.0, < 3` - - `^0.2.3` is equivalent to `>=0.2.3 <0.3.0` - - `^0.2` is equivalent to `>=0.2.0 <0.3.0` - - `^0.0.3` is equivalent to `>=0.0.3 <0.0.4` - - `^0.0` is equivalent to `>=0.0.0 <0.1.0` - - `^0` is equivalent to `>=0.0.0 <1.0.0` - -# Validation - -In addition to testing a version against a constraint, a version can be validated -against a constraint. When validation fails a slice of errors containing why a -version didn't meet the constraint is returned. For example, - - c, err := semver.NewConstraint("<= 1.2.3, >= 1.4") - if err != nil { - // Handle constraint not being parseable. - } - - v, _ := semver.NewVersion("1.3") - if err != nil { - // Handle version not being parseable. - } - - // Validate a version against a constraint. - a, msgs := c.Validate(v) - // a is false - for _, m := range msgs { - fmt.Println(m) - - // Loops over the errors which would read - // "1.3 is greater than 1.2.3" - // "1.3 is less than 1.4" - } -*/ -package semver diff --git a/go-controller/vendor/github.com/Masterminds/semver/v3/version.go b/go-controller/vendor/github.com/Masterminds/semver/v3/version.go deleted file mode 100644 index 7c4bed3347..0000000000 --- a/go-controller/vendor/github.com/Masterminds/semver/v3/version.go +++ /dev/null @@ -1,639 +0,0 @@ -package semver - -import ( - "bytes" - "database/sql/driver" - "encoding/json" - "errors" - "fmt" - "regexp" - "strconv" - "strings" -) - -// The compiled version of the regex created at init() is cached here so it -// only needs to be created once. -var versionRegex *regexp.Regexp - -var ( - // ErrInvalidSemVer is returned a version is found to be invalid when - // being parsed. - ErrInvalidSemVer = errors.New("Invalid Semantic Version") - - // ErrEmptyString is returned when an empty string is passed in for parsing. - ErrEmptyString = errors.New("Version string empty") - - // ErrInvalidCharacters is returned when invalid characters are found as - // part of a version - ErrInvalidCharacters = errors.New("Invalid characters in version") - - // ErrSegmentStartsZero is returned when a version segment starts with 0. - // This is invalid in SemVer. - ErrSegmentStartsZero = errors.New("Version segment starts with 0") - - // ErrInvalidMetadata is returned when the metadata is an invalid format - ErrInvalidMetadata = errors.New("Invalid Metadata string") - - // ErrInvalidPrerelease is returned when the pre-release is an invalid format - ErrInvalidPrerelease = errors.New("Invalid Prerelease string") -) - -// semVerRegex is the regular expression used to parse a semantic version. -const semVerRegex string = `v?([0-9]+)(\.[0-9]+)?(\.[0-9]+)?` + - `(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` + - `(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` - -// Version represents a single semantic version. -type Version struct { - major, minor, patch uint64 - pre string - metadata string - original string -} - -func init() { - versionRegex = regexp.MustCompile("^" + semVerRegex + "$") -} - -const ( - num string = "0123456789" - allowed string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-" + num -) - -// StrictNewVersion parses a given version and returns an instance of Version or -// an error if unable to parse the version. Only parses valid semantic versions. -// Performs checking that can find errors within the version. -// If you want to coerce a version such as 1 or 1.2 and parse it as the 1.x -// releases of semver did, use the NewVersion() function. -func StrictNewVersion(v string) (*Version, error) { - // Parsing here does not use RegEx in order to increase performance and reduce - // allocations. - - if len(v) == 0 { - return nil, ErrEmptyString - } - - // Split the parts into [0]major, [1]minor, and [2]patch,prerelease,build - parts := strings.SplitN(v, ".", 3) - if len(parts) != 3 { - return nil, ErrInvalidSemVer - } - - sv := &Version{ - original: v, - } - - // check for prerelease or build metadata - var extra []string - if strings.ContainsAny(parts[2], "-+") { - // Start with the build metadata first as it needs to be on the right - extra = strings.SplitN(parts[2], "+", 2) - if len(extra) > 1 { - // build metadata found - sv.metadata = extra[1] - parts[2] = extra[0] - } - - extra = strings.SplitN(parts[2], "-", 2) - if len(extra) > 1 { - // prerelease found - sv.pre = extra[1] - parts[2] = extra[0] - } - } - - // Validate the number segments are valid. This includes only having positive - // numbers and no leading 0's. - for _, p := range parts { - if !containsOnly(p, num) { - return nil, ErrInvalidCharacters - } - - if len(p) > 1 && p[0] == '0' { - return nil, ErrSegmentStartsZero - } - } - - // Extract the major, minor, and patch elements onto the returned Version - var err error - sv.major, err = strconv.ParseUint(parts[0], 10, 64) - if err != nil { - return nil, err - } - - sv.minor, err = strconv.ParseUint(parts[1], 10, 64) - if err != nil { - return nil, err - } - - sv.patch, err = strconv.ParseUint(parts[2], 10, 64) - if err != nil { - return nil, err - } - - // No prerelease or build metadata found so returning now as a fastpath. - if sv.pre == "" && sv.metadata == "" { - return sv, nil - } - - if sv.pre != "" { - if err = validatePrerelease(sv.pre); err != nil { - return nil, err - } - } - - if sv.metadata != "" { - if err = validateMetadata(sv.metadata); err != nil { - return nil, err - } - } - - return sv, nil -} - -// NewVersion parses a given version and returns an instance of Version or -// an error if unable to parse the version. If the version is SemVer-ish it -// attempts to convert it to SemVer. If you want to validate it was a strict -// semantic version at parse time see StrictNewVersion(). -func NewVersion(v string) (*Version, error) { - m := versionRegex.FindStringSubmatch(v) - if m == nil { - return nil, ErrInvalidSemVer - } - - sv := &Version{ - metadata: m[8], - pre: m[5], - original: v, - } - - var err error - sv.major, err = strconv.ParseUint(m[1], 10, 64) - if err != nil { - return nil, fmt.Errorf("Error parsing version segment: %s", err) - } - - if m[2] != "" { - sv.minor, err = strconv.ParseUint(strings.TrimPrefix(m[2], "."), 10, 64) - if err != nil { - return nil, fmt.Errorf("Error parsing version segment: %s", err) - } - } else { - sv.minor = 0 - } - - if m[3] != "" { - sv.patch, err = strconv.ParseUint(strings.TrimPrefix(m[3], "."), 10, 64) - if err != nil { - return nil, fmt.Errorf("Error parsing version segment: %s", err) - } - } else { - sv.patch = 0 - } - - // Perform some basic due diligence on the extra parts to ensure they are - // valid. - - if sv.pre != "" { - if err = validatePrerelease(sv.pre); err != nil { - return nil, err - } - } - - if sv.metadata != "" { - if err = validateMetadata(sv.metadata); err != nil { - return nil, err - } - } - - return sv, nil -} - -// New creates a new instance of Version with each of the parts passed in as -// arguments instead of parsing a version string. -func New(major, minor, patch uint64, pre, metadata string) *Version { - v := Version{ - major: major, - minor: minor, - patch: patch, - pre: pre, - metadata: metadata, - original: "", - } - - v.original = v.String() - - return &v -} - -// MustParse parses a given version and panics on error. -func MustParse(v string) *Version { - sv, err := NewVersion(v) - if err != nil { - panic(err) - } - return sv -} - -// String converts a Version object to a string. -// Note, if the original version contained a leading v this version will not. -// See the Original() method to retrieve the original value. Semantic Versions -// don't contain a leading v per the spec. Instead it's optional on -// implementation. -func (v Version) String() string { - var buf bytes.Buffer - - fmt.Fprintf(&buf, "%d.%d.%d", v.major, v.minor, v.patch) - if v.pre != "" { - fmt.Fprintf(&buf, "-%s", v.pre) - } - if v.metadata != "" { - fmt.Fprintf(&buf, "+%s", v.metadata) - } - - return buf.String() -} - -// Original returns the original value passed in to be parsed. -func (v *Version) Original() string { - return v.original -} - -// Major returns the major version. -func (v Version) Major() uint64 { - return v.major -} - -// Minor returns the minor version. -func (v Version) Minor() uint64 { - return v.minor -} - -// Patch returns the patch version. -func (v Version) Patch() uint64 { - return v.patch -} - -// Prerelease returns the pre-release version. -func (v Version) Prerelease() string { - return v.pre -} - -// Metadata returns the metadata on the version. -func (v Version) Metadata() string { - return v.metadata -} - -// originalVPrefix returns the original 'v' prefix if any. -func (v Version) originalVPrefix() string { - // Note, only lowercase v is supported as a prefix by the parser. - if v.original != "" && v.original[:1] == "v" { - return v.original[:1] - } - return "" -} - -// IncPatch produces the next patch version. -// If the current version does not have prerelease/metadata information, -// it unsets metadata and prerelease values, increments patch number. -// If the current version has any of prerelease or metadata information, -// it unsets both values and keeps current patch value -func (v Version) IncPatch() Version { - vNext := v - // according to http://semver.org/#spec-item-9 - // Pre-release versions have a lower precedence than the associated normal version. - // according to http://semver.org/#spec-item-10 - // Build metadata SHOULD be ignored when determining version precedence. - if v.pre != "" { - vNext.metadata = "" - vNext.pre = "" - } else { - vNext.metadata = "" - vNext.pre = "" - vNext.patch = v.patch + 1 - } - vNext.original = v.originalVPrefix() + "" + vNext.String() - return vNext -} - -// IncMinor produces the next minor version. -// Sets patch to 0. -// Increments minor number. -// Unsets metadata. -// Unsets prerelease status. -func (v Version) IncMinor() Version { - vNext := v - vNext.metadata = "" - vNext.pre = "" - vNext.patch = 0 - vNext.minor = v.minor + 1 - vNext.original = v.originalVPrefix() + "" + vNext.String() - return vNext -} - -// IncMajor produces the next major version. -// Sets patch to 0. -// Sets minor to 0. -// Increments major number. -// Unsets metadata. -// Unsets prerelease status. -func (v Version) IncMajor() Version { - vNext := v - vNext.metadata = "" - vNext.pre = "" - vNext.patch = 0 - vNext.minor = 0 - vNext.major = v.major + 1 - vNext.original = v.originalVPrefix() + "" + vNext.String() - return vNext -} - -// SetPrerelease defines the prerelease value. -// Value must not include the required 'hyphen' prefix. -func (v Version) SetPrerelease(prerelease string) (Version, error) { - vNext := v - if len(prerelease) > 0 { - if err := validatePrerelease(prerelease); err != nil { - return vNext, err - } - } - vNext.pre = prerelease - vNext.original = v.originalVPrefix() + "" + vNext.String() - return vNext, nil -} - -// SetMetadata defines metadata value. -// Value must not include the required 'plus' prefix. -func (v Version) SetMetadata(metadata string) (Version, error) { - vNext := v - if len(metadata) > 0 { - if err := validateMetadata(metadata); err != nil { - return vNext, err - } - } - vNext.metadata = metadata - vNext.original = v.originalVPrefix() + "" + vNext.String() - return vNext, nil -} - -// LessThan tests if one version is less than another one. -func (v *Version) LessThan(o *Version) bool { - return v.Compare(o) < 0 -} - -// GreaterThan tests if one version is greater than another one. -func (v *Version) GreaterThan(o *Version) bool { - return v.Compare(o) > 0 -} - -// Equal tests if two versions are equal to each other. -// Note, versions can be equal with different metadata since metadata -// is not considered part of the comparable version. -func (v *Version) Equal(o *Version) bool { - return v.Compare(o) == 0 -} - -// Compare compares this version to another one. It returns -1, 0, or 1 if -// the version smaller, equal, or larger than the other version. -// -// Versions are compared by X.Y.Z. Build metadata is ignored. Prerelease is -// lower than the version without a prerelease. Compare always takes into account -// prereleases. If you want to work with ranges using typical range syntaxes that -// skip prereleases if the range is not looking for them use constraints. -func (v *Version) Compare(o *Version) int { - // Compare the major, minor, and patch version for differences. If a - // difference is found return the comparison. - if d := compareSegment(v.Major(), o.Major()); d != 0 { - return d - } - if d := compareSegment(v.Minor(), o.Minor()); d != 0 { - return d - } - if d := compareSegment(v.Patch(), o.Patch()); d != 0 { - return d - } - - // At this point the major, minor, and patch versions are the same. - ps := v.pre - po := o.Prerelease() - - if ps == "" && po == "" { - return 0 - } - if ps == "" { - return 1 - } - if po == "" { - return -1 - } - - return comparePrerelease(ps, po) -} - -// UnmarshalJSON implements JSON.Unmarshaler interface. -func (v *Version) UnmarshalJSON(b []byte) error { - var s string - if err := json.Unmarshal(b, &s); err != nil { - return err - } - temp, err := NewVersion(s) - if err != nil { - return err - } - v.major = temp.major - v.minor = temp.minor - v.patch = temp.patch - v.pre = temp.pre - v.metadata = temp.metadata - v.original = temp.original - return nil -} - -// MarshalJSON implements JSON.Marshaler interface. -func (v Version) MarshalJSON() ([]byte, error) { - return json.Marshal(v.String()) -} - -// UnmarshalText implements the encoding.TextUnmarshaler interface. -func (v *Version) UnmarshalText(text []byte) error { - temp, err := NewVersion(string(text)) - if err != nil { - return err - } - - *v = *temp - - return nil -} - -// MarshalText implements the encoding.TextMarshaler interface. -func (v Version) MarshalText() ([]byte, error) { - return []byte(v.String()), nil -} - -// Scan implements the SQL.Scanner interface. -func (v *Version) Scan(value interface{}) error { - var s string - s, _ = value.(string) - temp, err := NewVersion(s) - if err != nil { - return err - } - v.major = temp.major - v.minor = temp.minor - v.patch = temp.patch - v.pre = temp.pre - v.metadata = temp.metadata - v.original = temp.original - return nil -} - -// Value implements the Driver.Valuer interface. -func (v Version) Value() (driver.Value, error) { - return v.String(), nil -} - -func compareSegment(v, o uint64) int { - if v < o { - return -1 - } - if v > o { - return 1 - } - - return 0 -} - -func comparePrerelease(v, o string) int { - // split the prelease versions by their part. The separator, per the spec, - // is a . - sparts := strings.Split(v, ".") - oparts := strings.Split(o, ".") - - // Find the longer length of the parts to know how many loop iterations to - // go through. - slen := len(sparts) - olen := len(oparts) - - l := slen - if olen > slen { - l = olen - } - - // Iterate over each part of the prereleases to compare the differences. - for i := 0; i < l; i++ { - // Since the lentgh of the parts can be different we need to create - // a placeholder. This is to avoid out of bounds issues. - stemp := "" - if i < slen { - stemp = sparts[i] - } - - otemp := "" - if i < olen { - otemp = oparts[i] - } - - d := comparePrePart(stemp, otemp) - if d != 0 { - return d - } - } - - // Reaching here means two versions are of equal value but have different - // metadata (the part following a +). They are not identical in string form - // but the version comparison finds them to be equal. - return 0 -} - -func comparePrePart(s, o string) int { - // Fastpath if they are equal - if s == o { - return 0 - } - - // When s or o are empty we can use the other in an attempt to determine - // the response. - if s == "" { - if o != "" { - return -1 - } - return 1 - } - - if o == "" { - if s != "" { - return 1 - } - return -1 - } - - // When comparing strings "99" is greater than "103". To handle - // cases like this we need to detect numbers and compare them. According - // to the semver spec, numbers are always positive. If there is a - at the - // start like -99 this is to be evaluated as an alphanum. numbers always - // have precedence over alphanum. Parsing as Uints because negative numbers - // are ignored. - - oi, n1 := strconv.ParseUint(o, 10, 64) - si, n2 := strconv.ParseUint(s, 10, 64) - - // The case where both are strings compare the strings - if n1 != nil && n2 != nil { - if s > o { - return 1 - } - return -1 - } else if n1 != nil { - // o is a string and s is a number - return -1 - } else if n2 != nil { - // s is a string and o is a number - return 1 - } - // Both are numbers - if si > oi { - return 1 - } - return -1 -} - -// Like strings.ContainsAny but does an only instead of any. -func containsOnly(s string, comp string) bool { - return strings.IndexFunc(s, func(r rune) bool { - return !strings.ContainsRune(comp, r) - }) == -1 -} - -// From the spec, "Identifiers MUST comprise only -// ASCII alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty. -// Numeric identifiers MUST NOT include leading zeroes.". These segments can -// be dot separated. -func validatePrerelease(p string) error { - eparts := strings.Split(p, ".") - for _, p := range eparts { - if containsOnly(p, num) { - if len(p) > 1 && p[0] == '0' { - return ErrSegmentStartsZero - } - } else if !containsOnly(p, allowed) { - return ErrInvalidPrerelease - } - } - - return nil -} - -// From the spec, "Build metadata MAY be denoted by -// appending a plus sign and a series of dot separated identifiers immediately -// following the patch or pre-release version. Identifiers MUST comprise only -// ASCII alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty." -func validateMetadata(m string) error { - eparts := strings.Split(m, ".") - for _, p := range eparts { - if !containsOnly(p, allowed) { - return ErrInvalidMetadata - } - } - return nil -} diff --git a/go-controller/vendor/github.com/containernetworking/cni/libcni/api.go b/go-controller/vendor/github.com/containernetworking/cni/libcni/api.go index 5c7f3b028c..201a12e977 100644 --- a/go-controller/vendor/github.com/containernetworking/cni/libcni/api.go +++ b/go-controller/vendor/github.com/containernetworking/cni/libcni/api.go @@ -23,6 +23,7 @@ package libcni import ( "context" "encoding/json" + "errors" "fmt" "os" "path/filepath" @@ -75,6 +76,7 @@ type NetworkConfigList struct { Name string CNIVersion string DisableCheck bool + DisableGC bool Plugins []*NetworkConfig Bytes []byte } @@ -113,6 +115,8 @@ type CNI interface { GetStatusNetworkList(ctx context.Context, net *NetworkConfigList) error GetCachedAttachments(containerID string) ([]*NetworkAttachment, error) + + GetVersionInfo(ctx context.Context, pluginType string) (version.PluginInfo, error) } type CNIConfig struct { @@ -422,6 +426,9 @@ func (c *CNIConfig) GetCachedAttachments(containerID string) ([]*NetworkAttachme dirPath := filepath.Join(c.getCacheDir(&RuntimeConf{}), "results") entries, err := os.ReadDir(dirPath) if err != nil { + if os.IsNotExist(err) { + return nil, nil + } return nil, err } @@ -595,9 +602,7 @@ func (c *CNIConfig) DelNetworkList(ctx context.Context, list *NetworkConfigList, } } - if cachedResult != nil { - _ = c.cacheDel(list.Name, rt) - } + _ = c.cacheDel(list.Name, rt) return nil } @@ -758,15 +763,23 @@ func (c *CNIConfig) GetVersionInfo(ctx context.Context, pluginType string) (vers // - dump the list of cached attachments, and issue deletes as necessary // - issue a GC to the underlying plugins (if the version is high enough) func (c *CNIConfig) GCNetworkList(ctx context.Context, list *NetworkConfigList, args *GCArgs) error { + // If DisableGC is set, then don't bother GCing at all. + if list.DisableGC { + return nil + } + // First, get the list of cached attachments cachedAttachments, err := c.GetCachedAttachments("") if err != nil { return nil } - validAttachments := make(map[types.GCAttachment]interface{}, len(args.ValidAttachments)) - for _, a := range args.ValidAttachments { - validAttachments[a] = nil + var validAttachments map[types.GCAttachment]interface{} + if args != nil { + validAttachments = make(map[types.GCAttachment]interface{}, len(args.ValidAttachments)) + for _, a := range args.ValidAttachments { + validAttachments[a] = nil + } } var errs []error @@ -799,10 +812,15 @@ func (c *CNIConfig) GCNetworkList(ctx context.Context, list *NetworkConfigList, // now, if the version supports it, issue a GC if gt, _ := version.GreaterThanOrEqualTo(list.CNIVersion, "1.1.0"); gt { inject := map[string]interface{}{ - "name": list.Name, - "cniVersion": list.CNIVersion, - "cni.dev/valid-attachments": args.ValidAttachments, + "name": list.Name, + "cniVersion": list.CNIVersion, } + if args != nil { + inject["cni.dev/valid-attachments"] = args.ValidAttachments + // #1101: spec used incorrect variable name + inject["cni.dev/attachments"] = args.ValidAttachments + } + for _, plugin := range list.Plugins { // build config here pluginConfig, err := InjectConf(plugin, inject) @@ -815,7 +833,7 @@ func (c *CNIConfig) GCNetworkList(ctx context.Context, list *NetworkConfigList, } } - return joinErrors(errs...) + return errors.Join(errs...) } func (c *CNIConfig) gcNetwork(ctx context.Context, net *NetworkConfig) error { diff --git a/go-controller/vendor/github.com/containernetworking/cni/libcni/conf.go b/go-controller/vendor/github.com/containernetworking/cni/libcni/conf.go index 6c5d99de98..1d1b821c63 100644 --- a/go-controller/vendor/github.com/containernetworking/cni/libcni/conf.go +++ b/go-controller/vendor/github.com/containernetworking/cni/libcni/conf.go @@ -20,11 +20,10 @@ import ( "fmt" "os" "path/filepath" + "slices" "sort" "strings" - "github.com/Masterminds/semver/v3" - "github.com/containernetworking/cni/pkg/types" "github.com/containernetworking/cni/pkg/version" ) @@ -92,24 +91,20 @@ func ConfListFromBytes(bytes []byte) (*NetworkConfigList, error) { rawVersions, ok := rawList["cniVersions"] if ok { // Parse the current package CNI version - currentVersion, err := semver.NewVersion(version.Current()) - if err != nil { - panic("CNI version is invalid semver!") - } - rvs, ok := rawVersions.([]interface{}) if !ok { return nil, fmt.Errorf("error parsing configuration list: invalid type for cniVersions: %T", rvs) } - vs := make([]*semver.Version, 0, len(rvs)) + vs := make([]string, 0, len(rvs)) for i, rv := range rvs { v, ok := rv.(string) if !ok { return nil, fmt.Errorf("error parsing configuration list: invalid type for cniVersions index %d: %T", i, rv) } - if v, err := semver.NewVersion(v); err != nil { + gt, err := version.GreaterThan(v, version.Current()) + if err != nil { return nil, fmt.Errorf("error parsing configuration list: invalid cniVersions entry %s at index %d: %w", v, i, err) - } else if !v.GreaterThan(currentVersion) { + } else if !gt { // Skip versions "greater" than this implementation of the spec vs = append(vs, v) } @@ -117,41 +112,65 @@ func ConfListFromBytes(bytes []byte) (*NetworkConfigList, error) { // if cniVersion was already set, append it to the list for sorting. if cniVersion != "" { - if v, err := semver.NewVersion(cniVersion); err != nil { + gt, err := version.GreaterThan(cniVersion, version.Current()) + if err != nil { return nil, fmt.Errorf("error parsing configuration list: invalid cniVersion %s: %w", cniVersion, err) - } else if !v.GreaterThan(currentVersion) { + } else if !gt { // ignore any versions higher than the current implemented spec version - vs = append(vs, v) + vs = append(vs, cniVersion) } } - sort.Sort(semver.Collection(vs)) + slices.SortFunc[[]string](vs, func(v1, v2 string) int { + if v1 == v2 { + return 0 + } + if gt, _ := version.GreaterThan(v1, v2); gt { + return 1 + } + return -1 + }) if len(vs) > 0 { - cniVersion = vs[len(vs)-1].String() + cniVersion = vs[len(vs)-1] } } - disableCheck := false - if rawDisableCheck, ok := rawList["disableCheck"]; ok { - disableCheck, ok = rawDisableCheck.(bool) + readBool := func(key string) (bool, error) { + rawVal, ok := rawList[key] if !ok { - disableCheckStr, ok := rawDisableCheck.(string) - if !ok { - return nil, fmt.Errorf("error parsing configuration list: invalid disableCheck type %T", rawDisableCheck) - } - switch { - case strings.ToLower(disableCheckStr) == "false": - disableCheck = false - case strings.ToLower(disableCheckStr) == "true": - disableCheck = true - default: - return nil, fmt.Errorf("error parsing configuration list: invalid disableCheck value %q", disableCheckStr) - } + return false, nil + } + if b, ok := rawVal.(bool); ok { + return b, nil } + + s, ok := rawVal.(string) + if !ok { + return false, fmt.Errorf("error parsing configuration list: invalid type %T for %s", rawVal, key) + } + s = strings.ToLower(s) + switch s { + case "false": + return false, nil + case "true": + return true, nil + } + return false, fmt.Errorf("error parsing configuration list: invalid value %q for %s", s, key) + } + + disableCheck, err := readBool("disableCheck") + if err != nil { + return nil, err + } + + disableGC, err := readBool("disableGC") + if err != nil { + return nil, err } list := &NetworkConfigList{ Name: name, DisableCheck: disableCheck, + DisableGC: disableGC, CNIVersion: cniVersion, Bytes: bytes, } diff --git a/go-controller/vendor/github.com/containernetworking/cni/libcni/multierror.go b/go-controller/vendor/github.com/containernetworking/cni/libcni/multierror.go deleted file mode 100644 index 100fb8392d..0000000000 --- a/go-controller/vendor/github.com/containernetworking/cni/libcni/multierror.go +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Copyright the CNI authors -// -// 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. -// -// Adapted from errors/join.go from go 1.20 -// This package can be removed once the toolchain is updated to 1.20 - -package libcni - -func joinErrors(errs ...error) error { - n := 0 - for _, err := range errs { - if err != nil { - n++ - } - } - if n == 0 { - return nil - } - e := &multiError{ - errs: make([]error, 0, n), - } - for _, err := range errs { - if err != nil { - e.errs = append(e.errs, err) - } - } - return e -} - -type multiError struct { - errs []error -} - -func (e *multiError) Error() string { - var b []byte - for i, err := range e.errs { - if i > 0 { - b = append(b, '\n') - } - b = append(b, err.Error()...) - } - return string(b) -} diff --git a/go-controller/vendor/github.com/containernetworking/cni/pkg/ns/ns_darwin.go b/go-controller/vendor/github.com/containernetworking/cni/pkg/ns/ns_darwin.go new file mode 100644 index 0000000000..cffe136178 --- /dev/null +++ b/go-controller/vendor/github.com/containernetworking/cni/pkg/ns/ns_darwin.go @@ -0,0 +1,21 @@ +// Copyright 2022 CNI authors +// +// 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 ns + +import "github.com/containernetworking/cni/pkg/types" + +func CheckNetNS(nsPath string) (bool, *types.Error) { + return false, nil +} diff --git a/go-controller/vendor/github.com/containernetworking/cni/pkg/types/types.go b/go-controller/vendor/github.com/containernetworking/cni/pkg/types/types.go index 193ac46ef8..8453bb5d87 100644 --- a/go-controller/vendor/github.com/containernetworking/cni/pkg/types/types.go +++ b/go-controller/vendor/github.com/containernetworking/cni/pkg/types/types.go @@ -56,8 +56,8 @@ func (n *IPNet) UnmarshalJSON(data []byte) error { return nil } -// NetConf describes a network. -type NetConf struct { +// NetConfType describes a network. +type NetConfType struct { CNIVersion string `json:"cniVersion,omitempty"` Name string `json:"name,omitempty"` @@ -73,6 +73,9 @@ type NetConf struct { ValidAttachments []GCAttachment `json:"cni.dev/valid-attachments,omitempty"` } +// NetConf is defined as different type as custom MarshalJSON() and issue #1096 +type NetConf NetConfType + // GCAttachment is the parameters to a GC call -- namely, // the container ID and ifname pair that represents a // still-valid attachment. @@ -83,11 +86,11 @@ type GCAttachment struct { // Note: DNS should be omit if DNS is empty but default Marshal function // will output empty structure hence need to write a Marshal function -func (n *NetConf) MarshalJSON() ([]byte, error) { +func (n *NetConfType) MarshalJSON() ([]byte, error) { // use type alias to escape recursion for json.Marshal() to MarshalJSON() type fixObjType = NetConf - bytes, err := json.Marshal(fixObjType(*n)) //nolint:all + bytes, err := json.Marshal(fixObjType(*n)) if err != nil { return nil, err } @@ -119,6 +122,7 @@ type NetConfList struct { Name string `json:"name,omitempty"` DisableCheck bool `json:"disableCheck,omitempty"` + DisableGC bool `json:"disableGC,omitempty"` Plugins []*NetConf `json:"plugins,omitempty"` } diff --git a/go-controller/vendor/github.com/containernetworking/cni/pkg/version/plugin.go b/go-controller/vendor/github.com/containernetworking/cni/pkg/version/plugin.go index 17b22b6b0c..e3bd375bca 100644 --- a/go-controller/vendor/github.com/containernetworking/cni/pkg/version/plugin.go +++ b/go-controller/vendor/github.com/containernetworking/cni/pkg/version/plugin.go @@ -142,3 +142,27 @@ func GreaterThanOrEqualTo(version, otherVersion string) (bool, error) { } return false, nil } + +// GreaterThan returns true if the first version is greater than the second +func GreaterThan(version, otherVersion string) (bool, error) { + firstMajor, firstMinor, firstMicro, err := ParseVersion(version) + if err != nil { + return false, err + } + + secondMajor, secondMinor, secondMicro, err := ParseVersion(otherVersion) + if err != nil { + return false, err + } + + if firstMajor > secondMajor { + return true, nil + } else if firstMajor == secondMajor { + if firstMinor > secondMinor { + return true, nil + } else if firstMinor == secondMinor && firstMicro > secondMicro { + return true, nil + } + } + return false, nil +} diff --git a/go-controller/vendor/modules.txt b/go-controller/vendor/modules.txt index e3578ea166..7564f7a89c 100644 --- a/go-controller/vendor/modules.txt +++ b/go-controller/vendor/modules.txt @@ -1,6 +1,3 @@ -# github.com/Masterminds/semver/v3 v3.2.1 -## explicit; go 1.18 -github.com/Masterminds/semver/v3 # github.com/Microsoft/go-winio v0.6.2 ## explicit; go 1.21 github.com/Microsoft/go-winio @@ -59,8 +56,8 @@ github.com/cespare/xxhash/v2 # github.com/containerd/cgroups v1.1.0 ## explicit; go 1.17 github.com/containerd/cgroups/stats/v1 -# github.com/containernetworking/cni v1.2.0-rc1 -## explicit; go 1.18 +# github.com/containernetworking/cni v1.2.3 +## explicit; go 1.21 github.com/containernetworking/cni/libcni github.com/containernetworking/cni/pkg/invoke github.com/containernetworking/cni/pkg/ns diff --git a/test/e2e/go.mod b/test/e2e/go.mod index a6a913d424..f336f1c7ce 100644 --- a/test/e2e/go.mod +++ b/test/e2e/go.mod @@ -25,7 +25,6 @@ require ( require ( cel.dev/expr v0.18.0 // indirect github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab // indirect - github.com/Masterminds/semver/v3 v3.2.1 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/NYTimes/gziphandler v1.1.1 // indirect github.com/antlr4-go/antlr/v4 v4.13.0 // indirect @@ -40,7 +39,7 @@ require ( github.com/containerd/errdefs v0.1.0 // indirect github.com/containerd/log v0.1.0 // indirect github.com/containerd/ttrpc v1.2.5 // indirect - github.com/containernetworking/cni v1.2.0-rc1 // indirect + github.com/containernetworking/cni v1.2.3 // indirect github.com/coreos/go-iptables v0.6.0 // indirect github.com/coreos/go-json v0.0.0-20230131223807-18775e0fb4fb // indirect github.com/coreos/go-semver v0.3.1 // indirect diff --git a/test/e2e/go.sum b/test/e2e/go.sum index 9df045a32f..ce895b56ed 100644 --- a/test/e2e/go.sum +++ b/test/e2e/go.sum @@ -51,8 +51,6 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab h1:UKkYhof1njT1/xq4SEg5z+VpTgjmNeHwPGRQl7takDI= github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab/go.mod h1:3VYc5hodBMJ5+l/7J4xAyMeuM2PNuepvHlGs8yilUCA= -github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= -github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= @@ -97,8 +95,8 @@ github.com/containerd/ttrpc v1.2.5 h1:IFckT1EFQoFBMG4c3sMdT8EP3/aKfumK1msY+Ze4oL github.com/containerd/ttrpc v1.2.5/go.mod h1:YCXHsb32f+Sq5/72xHubdiJRQY9inL4a4ZQrAbN1q9o= github.com/containerd/typeurl/v2 v2.2.0 h1:6NBDbQzr7I5LHgp34xAXYF5DOTQDn05X58lsPEmzLso= github.com/containerd/typeurl/v2 v2.2.0/go.mod h1:8XOOxnyatxSWuG8OfsZXVnAF4iZfedjS/8UHSPJnX4g= -github.com/containernetworking/cni v1.2.0-rc1 h1:AKI3+pXtgY4PDLN9+50o9IaywWVuey0Jkw3Lvzp0HCY= -github.com/containernetworking/cni v1.2.0-rc1/go.mod h1:Lt0TQcZQVDju64fYxUhDziTgXCDe3Olzi9I4zZJLWHg= +github.com/containernetworking/cni v1.2.3 h1:hhOcjNVUQTnzdRJ6alC5XF+wd9mfGIUaj8FuJbEslXM= +github.com/containernetworking/cni v1.2.3/go.mod h1:DuLgF+aPd3DzcTQTtp/Nvl1Kim23oFKdm2okJzBQA5M= github.com/containernetworking/plugins v1.2.0 h1:SWgg3dQG1yzUo4d9iD8cwSVh1VqI+bP7mkPDoSfP9VU= github.com/containernetworking/plugins v1.2.0/go.mod h1:/VjX4uHecW5vVimFa1wkG4s+r/s9qIfPdqlLF4TW8c4= github.com/coreos/butane v0.18.0 h1:WDeUC/dX1MUUVPwiqsQetQZsShNKk+2lrRXlC4ZhnZA= From 13bbcf264d26d6c2d292765d23c739c611b67302 Mon Sep 17 00:00:00 2001 From: Enrique Llorente Date: Thu, 19 Jun 2025 11:30:05 +0200 Subject: [PATCH 030/115] udn, util: Add ip, mac and ipamclaimref request to active network Signed-off-by: Enrique Llorente --- go-controller/pkg/util/multi_network.go | 42 +++++- go-controller/pkg/util/multi_network_test.go | 149 ++++++++++++++++++- 2 files changed, 182 insertions(+), 9 deletions(-) diff --git a/go-controller/pkg/util/multi_network.go b/go-controller/pkg/util/multi_network.go index bf1d3d6993..7819824d3e 100644 --- a/go-controller/pkg/util/multi_network.go +++ b/go-controller/pkg/util/multi_network.go @@ -1309,6 +1309,21 @@ func GetPodNADToNetworkMapping(pod *corev1.Pod, nInfo NetInfo) (bool, map[string return true, networkSelections, nil } +// overrideActiveNSEWithDefaultNSE overrides the provided active NetworkSelectionElement with the IP and MAC requests from +// the default NetworkSelectionElement after validating its namespace and name. +func overrideActiveNSEWithDefaultNSE(defaultNSE, activeNSE *nettypes.NetworkSelectionElement) error { + if defaultNSE.Namespace != config.Kubernetes.OVNConfigNamespace { + return fmt.Errorf("unexpected default NSE namespace %q, expected %q", defaultNSE.Namespace, config.Kubernetes.OVNConfigNamespace) + } + if defaultNSE.Name != types.DefaultNetworkName { + return fmt.Errorf("unexpected default NSE name %q, expected %q", defaultNSE.Name, types.DefaultNetworkName) + } + activeNSE.IPRequest = defaultNSE.IPRequest + activeNSE.MacRequest = defaultNSE.MacRequest + activeNSE.IPAMClaimReference = defaultNSE.IPAMClaimReference + return nil +} + // GetPodNADToNetworkMappingWithActiveNetwork will call `GetPodNADToNetworkMapping` passing "nInfo" which correspond // to the NetInfo representing the NAD, the resulting NetworkSelectingElements will be decorated with the ones // from found active network @@ -1337,18 +1352,39 @@ func GetPodNADToNetworkMappingWithActiveNetwork(pod *corev1.Pod, nInfo NetInfo, if len(networkSelections) == 0 { networkSelections = map[string]*nettypes.NetworkSelectionElement{} } - networkSelections[activeNetworkNADs[0]] = &nettypes.NetworkSelectionElement{ + + activeNSE := &nettypes.NetworkSelectionElement{ Namespace: activeNetworkNADKey[0], Name: activeNetworkNADKey[1], } - if nInfo.IsPrimaryNetwork() && AllowsPersistentIPs(nInfo) { + // Feature gate integration: EnablePreconfiguredUDNAddresses controls default network IP/MAC transfer to active network + if IsPreconfiguredUDNAddressesEnabled() { + // Limit the static ip and mac requests to the layer2 primary UDN when EnablePreconfiguredUDNAddresses is enabled, we + // don't need to explicitly check this is primary UDN since + // the "active network" concept is exactly that. + if activeNetwork.TopologyType() == types.Layer2Topology { + defaultNSE, err := GetK8sPodDefaultNetworkSelection(pod) + if err != nil { + return false, nil, fmt.Errorf("failed getting default-network annotation for pod %q: %w", pod.Namespace+"/"+pod.Name, err) + } + // If there are static IPs and MACs at the default NSE, override the active NSE with them + if defaultNSE != nil { + if err := overrideActiveNSEWithDefaultNSE(defaultNSE, activeNSE); err != nil { + return false, nil, err + } + } + } + } + + if nInfo.IsPrimaryNetwork() && AllowsPersistentIPs(nInfo) && activeNSE.IPAMClaimReference == "" { ipamClaimName, wasPersistentIPRequested := pod.Annotations[OvnUDNIPAMClaimName] if wasPersistentIPRequested { - networkSelections[activeNetworkNADs[0]].IPAMClaimReference = ipamClaimName + activeNSE.IPAMClaimReference = ipamClaimName } } + networkSelections[activeNetworkNADs[0]] = activeNSE return true, networkSelections, nil } diff --git a/go-controller/pkg/util/multi_network_test.go b/go-controller/pkg/util/multi_network_test.go index daaaf920a5..2c953464be 100644 --- a/go-controller/pkg/util/multi_network_test.go +++ b/go-controller/pkg/util/multi_network_test.go @@ -862,6 +862,7 @@ func TestGetPodNADToNetworkMappingWithActiveNetwork(t *testing.T) { expectedError error expectedIsAttachmentRequested bool expectedNetworkSelectionElements map[string]*nadv1.NetworkSelectionElement + enablePreconfiguredUDNAddresses bool } tests := []testConfig{ @@ -1011,10 +1012,143 @@ func TestGetPodNADToNetworkMappingWithActiveNetwork(t *testing.T) { }, }, }, + { + desc: "the network configuration for a primary layer2 UDN receive pod requesting IP, MAC and IPAMClaimRef on default network annotation for it", + inputNetConf: &ovncnitypes.NetConf{ + NetConf: cnitypes.NetConf{Name: networkName}, + Topology: ovntypes.Layer2Topology, + NADName: GetNADName(namespaceName, attachmentName), + Role: ovntypes.NetworkRolePrimary, + }, + inputPrimaryUDNConfig: &ovncnitypes.NetConf{ + NetConf: cnitypes.NetConf{Name: networkName}, + Topology: ovntypes.Layer2Topology, + NADName: GetNADName(namespaceName, attachmentName), + Role: ovntypes.NetworkRolePrimary, + }, + inputPodAnnotations: map[string]string{ + nadv1.NetworkAttachmentAnnot: GetNADName(namespaceName, "another-network"), + DefNetworkAnnotation: `[{"namespace": "ovn-kubernetes", "name": "default", "ips": ["192.168.0.3/24", "fda6::3/48"], "mac": "aa:bb:cc:dd:ee:ff", "ipam-claim-reference": "my-ipam-claim"}]`, + }, + expectedIsAttachmentRequested: true, + expectedNetworkSelectionElements: map[string]*nadv1.NetworkSelectionElement{ + "ns1/attachment1": { + Name: "attachment1", + Namespace: "ns1", + IPRequest: []string{"192.168.0.3/24", "fda6::3/48"}, + MacRequest: "aa:bb:cc:dd:ee:ff", + IPAMClaimReference: "my-ipam-claim", + }, + }, + enablePreconfiguredUDNAddresses: true, + }, + { + desc: "the network configuration for a primary layer2 UDN receive pod requesting IP and MAC on default network annotation for it, but with unexpected namespace", + inputNetConf: &ovncnitypes.NetConf{ + NetConf: cnitypes.NetConf{Name: networkName}, + Topology: ovntypes.Layer2Topology, + NADName: GetNADName(namespaceName, attachmentName), + Role: ovntypes.NetworkRolePrimary, + }, + inputPrimaryUDNConfig: &ovncnitypes.NetConf{ + NetConf: cnitypes.NetConf{Name: networkName}, + Topology: ovntypes.Layer2Topology, + NADName: GetNADName(namespaceName, attachmentName), + Role: ovntypes.NetworkRolePrimary, + }, + inputPodAnnotations: map[string]string{ + DefNetworkAnnotation: `[{"namespace": "other-namespace", "name": "default", "ips": ["192.168.0.3/24", "fda6::3/48"], "mac": "aa:bb:cc:dd:ee:ff"}]`, + }, + enablePreconfiguredUDNAddresses: true, + expectedError: fmt.Errorf(`unexpected default NSE namespace "other-namespace", expected "ovn-kubernetes"`), + }, + { + desc: "the network configuration for a primary layer2 UDN receive pod requesting IP and MAC on default network annotation for it, but with unexpected name", + inputNetConf: &ovncnitypes.NetConf{ + NetConf: cnitypes.NetConf{Name: networkName}, + Topology: ovntypes.Layer2Topology, + NADName: GetNADName(namespaceName, attachmentName), + Role: ovntypes.NetworkRolePrimary, + }, + inputPrimaryUDNConfig: &ovncnitypes.NetConf{ + NetConf: cnitypes.NetConf{Name: networkName}, + Topology: ovntypes.Layer2Topology, + NADName: GetNADName(namespaceName, attachmentName), + Role: ovntypes.NetworkRolePrimary, + }, + inputPodAnnotations: map[string]string{ + DefNetworkAnnotation: `[{"namespace": "ovn-kubernetes", "name": "unexpected-name", "ips": ["192.168.0.3/24", "fda6::3/48"], "mac": "aa:bb:cc:dd:ee:ff"}]`, + }, + enablePreconfiguredUDNAddresses: true, + expectedError: fmt.Errorf(`unexpected default NSE name "unexpected-name", expected "default"`), + }, + + { + desc: "default-network ips and mac is is ignored for Layer3 topology", + inputNetConf: &ovncnitypes.NetConf{ + NetConf: cnitypes.NetConf{Name: networkName}, + Topology: ovntypes.Layer3Topology, + NADName: GetNADName(namespaceName, attachmentName), + Role: ovntypes.NetworkRolePrimary, + }, + inputPrimaryUDNConfig: &ovncnitypes.NetConf{ + NetConf: cnitypes.NetConf{Name: networkName}, + Topology: ovntypes.Layer3Topology, + NADName: GetNADName(namespaceName, attachmentName), + Role: ovntypes.NetworkRolePrimary, + }, + inputPodAnnotations: map[string]string{ + nadv1.NetworkAttachmentAnnot: GetNADName(namespaceName, "another-network"), + DefNetworkAnnotation: `[{"namespace": "ovn-kubernetes", "name": "default", "ips": ["192.168.0.3/24", "fda6::3/48"], "mac": "aa:bb:cc:dd:ee:ff"}]`, + }, + expectedIsAttachmentRequested: true, + expectedNetworkSelectionElements: map[string]*nadv1.NetworkSelectionElement{ + "ns1/attachment1": { + Name: "attachment1", + Namespace: "ns1", + IPRequest: nil, + MacRequest: "", + }, + }, + enablePreconfiguredUDNAddresses: true, + }, + { + desc: "default-network with bad format", + inputNetConf: &ovncnitypes.NetConf{ + NetConf: cnitypes.NetConf{Name: networkName}, + Topology: ovntypes.Layer2Topology, + NADName: GetNADName(namespaceName, attachmentName), + Role: ovntypes.NetworkRolePrimary, + }, + inputPrimaryUDNConfig: &ovncnitypes.NetConf{ + NetConf: cnitypes.NetConf{Name: networkName}, + Topology: ovntypes.Layer2Topology, + NADName: GetNADName(namespaceName, attachmentName), + Role: ovntypes.NetworkRolePrimary, + }, + inputPodAnnotations: map[string]string{ + nadv1.NetworkAttachmentAnnot: GetNADName(namespaceName, "another-network"), + DefNetworkAnnotation: `[{"foo}`, + }, + enablePreconfiguredUDNAddresses: true, + expectedError: fmt.Errorf(`failed getting default-network annotation for pod "/test-pod": %w`, fmt.Errorf(`GetK8sPodDefaultNetwork: failed to parse CRD object: parsePodNetworkAnnotation: failed to parse pod Network Attachment Selection Annotation JSON format: unexpected end of JSON input`)), + }, } for _, test := range tests { t.Run(test.desc, func(t *testing.T) { g := gomega.NewWithT(t) + + t.Cleanup(func() { + _ = config.PrepareTestConfig() + }) + + // Set custom network config based on test requirements + config.OVNKubernetesFeature.EnablePreconfiguredUDNAddresses = test.enablePreconfiguredUDNAddresses + if test.enablePreconfiguredUDNAddresses { + config.OVNKubernetesFeature.EnableMultiNetwork = true + config.OVNKubernetesFeature.EnableNetworkSegmentation = true + } + netInfo, err := NewNetInfo(test.inputNetConf) g.Expect(err).ToNot(gomega.HaveOccurred()) if test.inputNetConf.NADName != "" { @@ -1048,11 +1182,14 @@ func TestGetPodNADToNetworkMappingWithActiveNetwork(t *testing.T) { primaryUDNNetInfo, ) - if err != nil { + if test.expectedError != nil { + g.Expect(err).To(gomega.HaveOccurred(), "unexpected success operation, epecting error") g.Expect(err).To(gomega.MatchError(test.expectedError)) + } else { + g.Expect(err).ToNot(gomega.HaveOccurred()) + g.Expect(isAttachmentRequested).To(gomega.Equal(test.expectedIsAttachmentRequested)) + g.Expect(networkSelectionElements).To(gomega.Equal(test.expectedNetworkSelectionElements)) } - g.Expect(isAttachmentRequested).To(gomega.Equal(test.expectedIsAttachmentRequested)) - g.Expect(networkSelectionElements).To(gomega.Equal(test.expectedNetworkSelectionElements)) }) } } @@ -1261,10 +1398,10 @@ func TestNewNetInfo(t *testing.T) { config.IPv6Mode = test.ipv6Cluster g := gomega.NewWithT(t) _, err := NewNetInfo(inputNetConf) - if test.expectedError == nil { - g.Expect(err).ToNot(gomega.HaveOccurred()) + if test.expectedError != nil { + g.Expect(err).To(gomega.MatchError(test.expectedError), "should return an error for invalid network configuration") } else { - g.Expect(err).To(gomega.MatchError(test.expectedError.Error())) + g.Expect(err).NotTo(gomega.HaveOccurred(), "should not return an error for valid network configuration") } }) } From 532d9919bb2ea5dfe22b68f851804d902e162dda Mon Sep 17 00:00:00 2001 From: Enrique Llorente Date: Mon, 23 Jun 2025 07:29:41 +0200 Subject: [PATCH 031/115] allocator: Allow static IP with ipam Signed-off-by: Enrique Llorente --- .../pkg/allocator/pod/pod_annotation.go | 33 ++- .../pkg/allocator/pod/pod_annotation_test.go | 201 +++++++++++++----- go-controller/pkg/util/pod_annotation.go | 2 +- 3 files changed, 178 insertions(+), 58 deletions(-) diff --git a/go-controller/pkg/allocator/pod/pod_annotation.go b/go-controller/pkg/allocator/pod/pod_annotation.go index 940952f7ff..cca6761845 100644 --- a/go-controller/pkg/allocator/pod/pod_annotation.go +++ b/go-controller/pkg/allocator/pod/pod_annotation.go @@ -207,6 +207,28 @@ func allocatePodAnnotationWithTunnelID( return pod, podAnnotation, nil } +// validateStaticIPRequest checks if a static IP request can be honored when IPAM is enabled for the given network. +func validateStaticIPRequest(netInfo util.NetInfo, podDesc string) error { + // Allow static IPs with IPAM only for primary networks with layer2 topology when EnablePreconfiguredUDNAddresses is enabled + // Feature gate integration: EnablePreconfiguredUDNAddresses controls static IP allocation with IPAM + if !util.IsPreconfiguredUDNAddressesEnabled() { + // Feature is disabled, reject static IPs with IPAM + return fmt.Errorf("cannot allocate a static IP request with IPAM for pod %s (custom network configuration disabled)", podDesc) + } + if !netInfo.IsPrimaryNetwork() { + // Static IP requests with IPAM are only supported on primary networks + return fmt.Errorf("cannot allocate a static IP request with IPAM for pod %s: only supported on primary networks", podDesc) + } + if netInfo.TopologyType() != types.Layer2Topology { + // Static IP requests with IPAM are only supported on layer2 topology networks. + // On other topologies, we cannot distinguish between already allocated IPs and + // IPs excluded from allocation, making it impossible to safely honor static IP + // requests when IPAM is enabled. + return fmt.Errorf("cannot allocate a static IP request with IPAM for pod %s: layer2 topology is required, but network has topology %q", podDesc, netInfo.TopologyType()) + } + return nil +} + // allocatePodAnnotationWithRollback allocates the PodAnnotation which includes // IPs, a mac address, routes, gateways and an ID. Returns the allocated pod // annotation and a pod with that annotation set. Returns a nil pod and the existing @@ -330,13 +352,11 @@ func allocatePodAnnotationWithRollback( } hasIPAMClaim = ipamClaim != nil && len(ipamClaim.Status.IPs) > 0 } + if hasIPAM && hasStaticIPRequest { - // for now we can't tell apart already allocated IPs from IPs excluded - // from allocation so we can't really honor static IP requests when - // there is IPAM as we don't really know if the requested IP should not - // be allocated or was already allocated by the same pod - err = fmt.Errorf("cannot allocate a static IP request with IPAM for pod %s", podDesc) - return + if err = validateStaticIPRequest(netInfo, podDesc); err != nil { + return + } } // we need to update the annotation if it is missing IPs or MAC @@ -348,6 +368,7 @@ func allocatePodAnnotationWithRollback( if hasIPRequest { tentative.IPs, err = util.ParseIPNets(network.IPRequest) if err != nil { + klog.Warningf("Failed parsing IPRequest %+v for pod %s: %v", network.IPRequest, podDesc, err) return } } else if hasIPAMClaim { diff --git a/go-controller/pkg/allocator/pod/pod_annotation_test.go b/go-controller/pkg/allocator/pod/pod_annotation_test.go index 7930bd0e11..a01a8f7bcd 100644 --- a/go-controller/pkg/allocator/pod/pod_annotation_test.go +++ b/go-controller/pkg/allocator/pod/pod_annotation_test.go @@ -109,25 +109,28 @@ func Test_allocatePodAnnotationWithRollback(t *testing.T) { reallocate bool } tests := []struct { - name string - args args - ipam bool - idAllocation bool - persistentIPAllocation bool - role string - podAnnotation *util.PodAnnotation - invalidNetworkAnnotation bool - wantUpdatedPod bool - wantGeneratedMac bool - wantPodAnnotation *util.PodAnnotation - wantReleasedIPs []*net.IPNet - wantReleasedIPsOnRollback []*net.IPNet - wantReleaseID bool - wantRelasedIDOnRollback bool - wantErr bool - isSingleStackIPv4 bool - isSingleStackIPv6 bool - multiNetworkDisabled bool + name string + args args + netInfo util.NetInfo + nadName string + ipam bool + idAllocation bool + persistentIPAllocation bool + enablePreconfiguredUDNAddresses bool + role string + podAnnotation *util.PodAnnotation + invalidNetworkAnnotation bool + wantUpdatedPod bool + wantGeneratedMac bool + wantPodAnnotation *util.PodAnnotation + wantReleasedIPs []*net.IPNet + wantReleasedIPsOnRollback []*net.IPNet + wantReleaseID bool + wantRelasedIDOnRollback bool + wantErr bool + isSingleStackIPv4 bool + isSingleStackIPv6 bool + multiNetworkDisabled bool }{ { // on secondary L2 networks with no IPAM, we expect to generate a @@ -195,8 +198,9 @@ func Test_allocatePodAnnotationWithRollback(t *testing.T) { { // on networks with IPAM, expect error if static IP request present // in the network selection annotation - name: "expect error, static ip request, IPAM", - ipam: true, + name: "expect error, static ip request, IPAM, non layer2", + netInfo: &util.DefaultNetInfo{}, + nadName: types.DefaultNetworkName, args: args{ network: &nadapi.NetworkSelectionElement{ IPRequest: []string{"192.168.0.3/24"}, @@ -540,9 +544,9 @@ func Test_allocatePodAnnotationWithRollback(t *testing.T) { wantReleasedIPs: ovntest.MustParseIPNets("192.168.0.3/24"), }, { - // on networks with IPAM, honor a MAC request through the network + // on networks with IPAM, honor a IP and MAC request through the network // selection element - name: "expect requested MAC", + name: "expect requested MAC, IPAM", ipam: true, args: args{ network: &nadapi.NetworkSelectionElement{ @@ -575,6 +579,99 @@ func Test_allocatePodAnnotationWithRollback(t *testing.T) { wantReleasedIPsOnRollback: ovntest.MustParseIPNets("192.168.0.3/24"), role: types.NetworkRolePrimary, // has to be primary network for default routes to be set }, + { + // on primary networks with IPAM and layer2 topology, expect success when EnablePreconfiguredUDNAddresses is enabled + name: "expect success, static IP and MAC with IPAM on primary network when EnablePreconfiguredUDNAddresses is enabled", + ipam: true, + enablePreconfiguredUDNAddresses: true, + role: types.NetworkRolePrimary, // has to be primary network for default routes to be set + persistentIPAllocation: true, + args: args{ + network: &nadapi.NetworkSelectionElement{ + MacRequest: requestedMAC, + IPRequest: []string{"192.168.0.101/24"}, + }, + ipAllocator: &ipAllocatorStub{ + nextIPs: ovntest.MustParseIPNets("192.168.0.3/24"), + }, + }, + wantUpdatedPod: true, + wantPodAnnotation: &util.PodAnnotation{ + IPs: ovntest.MustParseIPNets("192.168.0.101/24"), + MAC: requestedMACParsed, + Gateways: []net.IP{ovntest.MustParseIP("192.168.0.1").To4()}, + Routes: []util.PodRoute{ + { + Dest: ovntest.MustParseIPNet("100.65.0.0/16"), + NextHop: ovntest.MustParseIP("192.168.0.1").To4(), + }, + }, + Role: types.NetworkRolePrimary, + }, + wantReleasedIPsOnRollback: ovntest.MustParseIPNets("192.168.0.101/24"), + }, + { + // on primary networks with IPAM and layer2 topology, expect success when EnablePreconfiguredUDNAddresses is enabled + name: "expect success, just static IP with IPAM on primary network when EnablePreconfiguredUDNAddresses is enabled", + ipam: true, + enablePreconfiguredUDNAddresses: true, + persistentIPAllocation: true, + role: types.NetworkRolePrimary, + args: args{ + network: &nadapi.NetworkSelectionElement{ + IPRequest: []string{"192.168.0.101/24"}, + }, + ipAllocator: &ipAllocatorStub{ + nextIPs: ovntest.MustParseIPNets("192.168.0.101/24"), + }, + }, + wantUpdatedPod: true, + wantPodAnnotation: &util.PodAnnotation{ + IPs: ovntest.MustParseIPNets("192.168.0.101/24"), + MAC: util.IPAddrToHWAddr(ovntest.MustParseIPNets("192.168.0.101/24")[0].IP), + Gateways: []net.IP{ovntest.MustParseIP("192.168.0.1").To4()}, + Routes: []util.PodRoute{ + { + Dest: &net.IPNet{ + IP: ovntest.MustParseIP("100.65.0.0").To4(), + Mask: net.CIDRMask(16, 32), + }, + NextHop: ovntest.MustParseIP("192.168.0.1").To4(), + }, + }, + Role: types.NetworkRolePrimary, + }, + wantReleasedIPsOnRollback: ovntest.MustParseIPNets("192.168.0.101/24"), + }, + + { + // on networks with IPAM and layer2 topology, expect error when EnablePreconfiguredUDNAddresses is false + name: "expect error, static IP with IPAM on layer2 when EnablePreconfiguredUDNAddresses is false", + ipam: true, + role: types.NetworkRolePrimary, + persistentIPAllocation: true, + // enablePreconfiguredUDNAddresses defaults to false + args: args{ + network: &nadapi.NetworkSelectionElement{ + IPRequest: []string{"192.168.0.101/24"}, + }, + }, + wantErr: true, + }, + { + // with preconfigured UDN address feature enabled still continue failing with secondary layer2 with ipam + static IPs + name: "expect error, static IP with IPAM on secondary network when EnablePreconfiguredUDNAddresses is enabled", + ipam: true, + enablePreconfiguredUDNAddresses: true, + persistentIPAllocation: true, + args: args{ + network: &nadapi.NetworkSelectionElement{ + IPRequest: []string{"192.168.0.101/24"}, + }, + }, + role: types.NetworkRoleSecondary, + wantErr: true, + }, { // on networks with IPAM, expect error on an invalid network // selection element @@ -777,6 +874,7 @@ func Test_allocatePodAnnotationWithRollback(t *testing.T) { config.OVNKubernetesFeature.EnableInterconnect = tt.idAllocation config.OVNKubernetesFeature.EnableMultiNetwork = !tt.multiNetworkDisabled config.OVNKubernetesFeature.EnableNetworkSegmentation = true + config.OVNKubernetesFeature.EnablePreconfiguredUDNAddresses = tt.enablePreconfiguredUDNAddresses config.IPv4Mode = true if tt.isSingleStackIPv6 { config.IPv4Mode = false @@ -785,32 +883,33 @@ func Test_allocatePodAnnotationWithRollback(t *testing.T) { if tt.isSingleStackIPv4 { config.IPv6Mode = false } - var netInfo util.NetInfo - netInfo = &util.DefaultNetInfo{} - nadName := types.DefaultNetworkName - if !tt.ipam || tt.idAllocation || tt.persistentIPAllocation || tt.args.ipamClaim != nil { - nadName = util.GetNADName(network.Namespace, network.Name) - var subnets string - if tt.ipam { - subnets = "192.168.0.0/24,2001:db8::/64" - if tt.isSingleStackIPv4 { - subnets = "192.168.0.0/24" - } else if tt.isSingleStackIPv6 { - subnets = "2001:db8::/64" + if tt.netInfo == nil { + tt.netInfo = &util.DefaultNetInfo{} + tt.nadName = types.DefaultNetworkName + if !tt.ipam || tt.idAllocation || tt.persistentIPAllocation || tt.args.ipamClaim != nil { + tt.nadName = util.GetNADName(network.Namespace, network.Name) + var subnets string + if tt.ipam { + subnets = "192.168.0.0/24,2001:db8::/64" + if tt.isSingleStackIPv4 { + subnets = "192.168.0.0/24" + } else if tt.isSingleStackIPv6 { + subnets = "2001:db8::/64" + } + } + tt.netInfo, err = util.NewNetInfo(&ovncnitypes.NetConf{ + Topology: types.Layer2Topology, + NetConf: cnitypes.NetConf{ + Name: network.Name, + }, + NADName: tt.nadName, + Subnets: subnets, + AllowPersistentIPs: tt.persistentIPAllocation, + Role: tt.role, + }) + if err != nil { + t.Fatalf("failed to create NetInfo: %v", err) } - } - netInfo, err = util.NewNetInfo(&ovncnitypes.NetConf{ - Topology: types.Layer2Topology, - NetConf: cnitypes.NetConf{ - Name: network.Name, - }, - NADName: nadName, - Subnets: subnets, - AllowPersistentIPs: tt.persistentIPAllocation, - Role: tt.role, - }) - if err != nil { - t.Fatalf("failed to create NetInfo: %v", err) } } @@ -836,7 +935,7 @@ func Test_allocatePodAnnotationWithRollback(t *testing.T) { }, } if tt.podAnnotation != nil { - pod.Annotations, err = util.MarshalPodAnnotation(nil, tt.podAnnotation, nadName) + pod.Annotations, err = util.MarshalPodAnnotation(nil, tt.podAnnotation, tt.nadName) if err != nil { t.Fatalf("failed to set pod annotations: %v", err) } @@ -862,7 +961,7 @@ func Test_allocatePodAnnotationWithRollback(t *testing.T) { pod, podAnnotation, rollback, err := allocatePodAnnotationWithRollback( tt.args.ipAllocator, tt.args.idAllocator, - netInfo, + tt.netInfo, node, pod, network, @@ -887,7 +986,7 @@ func Test_allocatePodAnnotationWithRollback(t *testing.T) { if tt.args.ipAllocator != nil { releasedIPs := tt.args.ipAllocator.(*ipAllocatorStub).releasedIPs - g.Expect(releasedIPs).To(gomega.Equal(tt.wantReleasedIPsOnRollback), "Release IP on rollback behaved unexpectedly") + g.Expect(releasedIPs).To(gomega.Equal(tt.wantReleasedIPsOnRollback), "Release IP on rollback behaved unexpectedly: %s", tt.netInfo.TopologyType()) } if tt.args.idAllocator != nil { diff --git a/go-controller/pkg/util/pod_annotation.go b/go-controller/pkg/util/pod_annotation.go index b5c46a804f..0dc9f6af8a 100644 --- a/go-controller/pkg/util/pod_annotation.go +++ b/go-controller/pkg/util/pod_annotation.go @@ -53,7 +53,7 @@ import ( const ( // OvnPodAnnotationName is the constant string representing the POD annotation key OvnPodAnnotationName = "k8s.ovn.org/pod-networks" - // DefNetworkAnnotation is the pod annotation for the cluster-wide default network + // DefNetworkAnnotation is the pod annotation for the cluster-wide active network DefNetworkAnnotation = "v1.multus-cni.io/default-network" // OvnUDNIPAMClaimName is used for workload owners to instruct OVN-K which // IPAMClaim will hold the allocation for the workload From 6b76f22e2719e91bf2f5a865dd47e505d322a819 Mon Sep 17 00:00:00 2001 From: Enrique Llorente Date: Tue, 1 Jul 2025 10:00:57 +0200 Subject: [PATCH 032/115] gh, actions: Enable custon net conf for net-seg and virt Signed-off-by: Enrique Llorente --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d9d5d40eec..516dec2f43 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -513,6 +513,7 @@ jobs: TRAFFIC_FLOW_TESTS: "${{ matrix.traffic-flow-tests }}" ENABLE_ROUTE_ADVERTISEMENTS: "${{ matrix.routeadvertisements != '' }}" ADVERTISE_DEFAULT_NETWORK: "${{ matrix.routeadvertisements == 'advertise-default' }}" + ENABLE_PRE_CONF_UDN_ADDR: "${{ ( matrix.target == 'network-segmentation' || matrix.target == 'kv-live-migration' ) && matrix.ic == 'ic-single-node-zones' }}" steps: - name: Install VRF kernel module From 5679396a1c2206803b3dc770881ef2c621eb851d Mon Sep 17 00:00:00 2001 From: Enrique Llorente Date: Mon, 23 Jun 2025 14:54:06 +0200 Subject: [PATCH 033/115] e2e, kv: Add p-udn test for static ip and mac Signed-off-by: Enrique Llorente --- test/e2e/kubevirt.go | 68 +++++++++++++++++++++++++++++++++++----- test/e2e/kubevirt/pod.go | 17 ++++++++++ test/e2e/util.go | 24 ++++++++++++++ 3 files changed, 101 insertions(+), 8 deletions(-) diff --git a/test/e2e/kubevirt.go b/test/e2e/kubevirt.go index 67ab2e290a..19f628b464 100644 --- a/test/e2e/kubevirt.go +++ b/test/e2e/kubevirt.go @@ -1531,12 +1531,15 @@ fi cmd func() string } var ( - cudn *udnv1.ClusterUserDefinedNetwork - vm *kubevirtv1.VirtualMachine - vmi *kubevirtv1.VirtualMachineInstance - cidrIPv4 = "10.128.0.0/24" - cidrIPv6 = "2010:100:200::0/60" - restart = testCommand{ + cudn *udnv1.ClusterUserDefinedNetwork + vm *kubevirtv1.VirtualMachine + vmi *kubevirtv1.VirtualMachineInstance + cidrIPv4 = "10.128.0.0/24" + cidrIPv6 = "2010:100:200::0/60" + staticIPv4 = "10.128.0.101" + staticIPv6 = "2010:100:200::101" + staticMAC = "02:00:00:00:00:01" + restart = testCommand{ description: "restart", cmd: func() { By("Restarting vm") @@ -1619,6 +1622,29 @@ write_files: }, } + virtualMachineWithUDNAndStaticIPsAndMAC = resourceCommand{ + description: "VirtualMachine with interface binding for UDN and statics IPs and MAC", + cmd: func() string { + GinkgoHelper() + if !isPreConfiguredUdnAddressesEnabled() { + Skip("ENABLE_PRE_CONF_UDN_ADDR not configured") + } + + annotations, err := kubevirt.GenerateAddressesAnnotations("net1", filterIPs(fr.ClientSet, staticIPv4, staticIPv6)) + Expect(err).NotTo(HaveOccurred()) + + vm = fedoraWithTestToolingVM(nil /*labels*/, annotations, nil, /*nodeSelector*/ + kubevirtv1.NetworkSource{ + Pod: &kubevirtv1.PodNetwork{}, + }, userDataWithIperfServer, networkDataDualStack) + vm.Spec.Template.Spec.Domain.Devices.Interfaces[0].Bridge = nil + vm.Spec.Template.Spec.Domain.Devices.Interfaces[0].Binding = &kubevirtv1.PluginBinding{Name: "l2bridge"} + vm.Spec.Template.Spec.Domain.Devices.Interfaces[0].MacAddress = staticMAC + createVirtualMachine(vm) + return vm.Name + }, + } + virtualMachineInstance = resourceCommand{ description: "VirtualMachineInstance", cmd: func() string { @@ -1669,6 +1695,8 @@ write_files: topology udnv1.NetworkTopology role udnv1.NetworkRole ingress string + ipRequests []string + macRequest string } var ( containerNetwork = func(td testData) (infraapi.Network, error) { @@ -1817,6 +1845,12 @@ ip route add %[3]s via %[4]s step = by(vmi.Name, "Wait for addresses at the virtual machine") expectedNumberOfAddresses := len(dualCIDRs) expectedAddreses := virtualMachineAddressesFromStatus(vmi, expectedNumberOfAddresses) + if _, hasIPRequests := vmi.Annotations[kubevirt.AddressesAnnotation]; hasIPRequests { + Expect(expectedAddreses).To(ConsistOf(filterIPs(fr.ClientSet, staticIPv4, staticIPv6)), "expected addresses should be consistent with the static IPs") + } + if vmi.Spec.Domain.Devices.Interfaces[0].MacAddress != "" { + Expect(vmi.Spec.Domain.Devices.Interfaces[0].MacAddress).To(Equal(vmi.Status.Interfaces[0].MAC), "expected mac address should be consistent with the static MAC") + } expectedAddresesAtGuest := expectedAddreses testPodsIPs := podsMultusNetworkIPs(iperfServerTestPods, podNetworkStatusByNetConfigPredicate(namespace, cudn.Name, strings.ToLower(string(td.role)))) @@ -1988,6 +2022,25 @@ ip route add %[3]s via %[4]s topology: udnv1.NetworkTopologyLayer2, role: udnv1.NetworkRolePrimary, }), + Entry(nil, testData{ + resource: virtualMachineWithUDNAndStaticIPsAndMAC, + test: liveMigrate, + topology: udnv1.NetworkTopologyLayer2, + role: udnv1.NetworkRolePrimary, + }), + Entry(nil, testData{ + resource: virtualMachineWithUDNAndStaticIPsAndMAC, + test: restart, + topology: udnv1.NetworkTopologyLayer2, + role: udnv1.NetworkRolePrimary, + }), + Entry(nil, testData{ + resource: virtualMachineWithUDNAndStaticIPsAndMAC, + test: liveMigrate, + topology: udnv1.NetworkTopologyLayer2, + role: udnv1.NetworkRolePrimary, + ingress: "routed", + }), Entry(nil, testData{ resource: virtualMachineWithUDN, test: liveMigrate, @@ -2170,7 +2223,6 @@ ip route add %[3]s via %[4]s vmiIPv4 = "10.128.0.100/24" vmiIPv6 = "2010:100:200::100/60" vmiMAC = "0A:58:0A:80:00:64" - cidrs = []string{ipv4CIDR, ipv6CIDR} staticIPsNetworkData = func(ips []string) (string, error) { type Ethernet struct { Addresses []string `json:"addresses,omitempty"` @@ -2209,7 +2261,7 @@ chpasswd: { expire: False } selectedNodes = workerNodeList.Items Expect(selectedNodes).NotTo(BeEmpty()) - iperfServerTestPods, err = createIperfServerPods(selectedNodes, cudn.Name, cudn.Spec.Network.Localnet.Role, filterCIDRs(fr.ClientSet, cidrs...)) + iperfServerTestPods, err = createIperfServerPods(selectedNodes, cudn.Name, cudn.Spec.Network.Localnet.Role, filterCIDRs(fr.ClientSet, ipv4CIDR, ipv6CIDR)) Expect(err).NotTo(HaveOccurred()) networkData, err := staticIPsNetworkData(filterCIDRs(fr.ClientSet, vmiIPv4, vmiIPv6)) diff --git a/test/e2e/kubevirt/pod.go b/test/e2e/kubevirt/pod.go index 1293e1acc5..b6153e731a 100644 --- a/test/e2e/kubevirt/pod.go +++ b/test/e2e/kubevirt/pod.go @@ -1,6 +1,7 @@ package kubevirt import ( + "encoding/json" "fmt" infraapi "github.com/ovn-org/ovn-kubernetes/test/e2e/infraprovider/api" @@ -11,6 +12,10 @@ import ( kubevirtv1 "kubevirt.io/api/core/v1" ) +const ( + AddressesAnnotation = "network.kubevirt.io/addresses" +) + func GenerateFakeVirtLauncherPod(namespace, vmName string) *corev1.Pod { return &corev1.Pod{ ObjectMeta: metav1.ObjectMeta{ @@ -48,3 +53,15 @@ kill -9 $pid } return nil } + +func GenerateAddressesAnnotations(networkName string, addresses []string) (map[string]string, error) { + staticIPs, err := json.Marshal(map[string][]string{ + networkName: addresses, + }) + if err != nil { + return nil, fmt.Errorf("failed to marshal static IPs: %w", err) + } + return map[string]string{ + AddressesAnnotation: string(staticIPs), + }, nil +} diff --git a/test/e2e/util.go b/test/e2e/util.go index d03559e79e..ff7cfe66d1 100644 --- a/test/e2e/util.go +++ b/test/e2e/util.go @@ -32,6 +32,7 @@ import ( "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/kubernetes" + clientset "k8s.io/client-go/kubernetes" "k8s.io/kubernetes/test/e2e/framework" "k8s.io/kubernetes/test/e2e/framework/debug" e2ekubectl "k8s.io/kubernetes/test/e2e/framework/kubectl" @@ -1137,6 +1138,12 @@ func isCIDRIPFamilySupported(cs kubernetes.Interface, cidr string) bool { return (isIPv4Supported(cs) && !isIPv6) || (isIPv6Supported(cs) && isIPv6) } +func isIPFamilySupported(cs clientset.Interface, cidr string) bool { + ginkgo.GinkgoHelper() + isIPv6 := utilnet.IsIPv6String(cidr) + return (isIPv4Supported(cs) && !isIPv6) || (isIPv6Supported(cs) && isIPv6) +} + func isIPv4Supported(cs kubernetes.Interface) bool { v4, _ := getSupportedIPFamilies(cs) return v4 @@ -1147,6 +1154,17 @@ func isIPv6Supported(cs kubernetes.Interface) bool { return v6 } +func filterIPs(cs clientset.Interface, cidrs ...string) []string { + var supportedCIDRs []string + for _, cidr := range cidrs { + if !isIPFamilySupported(cs, cidr) { + continue + } + supportedCIDRs = append(supportedCIDRs, cidr) + } + return supportedCIDRs +} + func getSupportedIPFamilies(cs kubernetes.Interface) (bool, bool) { n, err := e2enode.GetRandomReadySchedulableNode(context.TODO(), cs) framework.ExpectNoError(err, "must fetch a Ready Node") @@ -1183,6 +1201,12 @@ func isLocalGWModeEnabled() bool { return present && val == "local" } +func isPreConfiguredUdnAddressesEnabled() bool { + ovnKubeNamespace := deploymentconfig.Get().OVNKubernetesNamespace() + val := getTemplateContainerEnv(ovnKubeNamespace, "daemonset/ovnkube-node", getNodeContainerName(), "OVN_PRE_CONF_UDN_ADDR_ENABLE") + return val == "true" +} + func singleNodePerZone() bool { if singleNodePerZoneResult == nil { args := []string{"get", "pods", "--selector=app=ovnkube-node", "-o", "jsonpath={.items[0].spec.containers[*].name}"} From d9f26e45cadd8172acf3a678b38c7cc936a32885 Mon Sep 17 00:00:00 2001 From: Enrique Llorente Date: Thu, 19 Jun 2025 09:44:26 +0200 Subject: [PATCH 034/115] e2e: Add happy test Signed-off-by: Enrique Llorente --- ...segmentation_default_network_annotation.go | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 test/e2e/network_segmentation_default_network_annotation.go diff --git a/test/e2e/network_segmentation_default_network_annotation.go b/test/e2e/network_segmentation_default_network_annotation.go new file mode 100644 index 0000000000..11849186f5 --- /dev/null +++ b/test/e2e/network_segmentation_default_network_annotation.go @@ -0,0 +1,106 @@ +package e2e + +import ( + "context" + "encoding/json" + "fmt" + "strings" + "time" + + nadapi "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + e2epod "k8s.io/kubernetes/test/e2e/framework/pod" + + udnv1 "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/crd/userdefinednetwork/v1" + udnclientset "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/crd/userdefinednetwork/v1/apis/clientset/versioned" +) + +var _ = Describe("Network Segmentation: Default network multus annotation", func() { + var ( + f = wrappedTestFramework("default-network-annotation") + ) + f.SkipNamespaceCreation = true + + type testCase struct { + ips []string + mac string + } + DescribeTable("when added with static IP and MAC to a pod belonging to primary UDN", func(tc testCase) { + if !isPreConfiguredUdnAddressesEnabled() { + Skip("ENABLE_PRE_CONF_UDN_ADDR not configured") + } + tc.ips = filterCIDRs(f.ClientSet, tc.ips...) + namespace, err := f.CreateNamespace(context.TODO(), f.BaseName, map[string]string{ + "e2e-framework": f.BaseName, + RequiredUDNNamespaceLabel: "", + }) + Expect(err).NotTo(HaveOccurred(), "Should create namespace for test") + f.Namespace = namespace + + // Create the UDN client using the framework's config + udnClient, err := udnclientset.NewForConfig(f.ClientConfig()) + Expect(err).NotTo(HaveOccurred(), "Should create UDN client") + + // Define the UserDefinedNetwork object + udn := &udnv1.UserDefinedNetwork{ + ObjectMeta: metav1.ObjectMeta{ + Name: "l2network", + Namespace: f.Namespace.Name, + }, + Spec: udnv1.UserDefinedNetworkSpec{ + Topology: udnv1.NetworkTopologyLayer2, + Layer2: &udnv1.Layer2Config{ + Role: udnv1.NetworkRolePrimary, + Subnets: filterDualStackCIDRs(f.ClientSet, []udnv1.CIDR{ + udnv1.CIDR("103.0.0.0/16"), + udnv1.CIDR("2014:100:200::0/60"), + }), + }, + }, + } + + // Create the resource in the generated namespace + By("Create a UserDefinedNetwork with Layer2 topology and wait for availability") + udn, err = udnClient.K8sV1().UserDefinedNetworks(f.Namespace.Name).Create(context.TODO(), udn, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred(), "Should create UserDefinedNetwork") + Eventually(userDefinedNetworkReadyFunc(f.DynamicClient, udn.Namespace, udn.Name), 5*time.Second, time.Second).Should(Succeed()) + + // Create the Pod in the generated namespace + By("Create a Pod with the default network annotation and wait for readiness") + ips, err := json.Marshal(tc.ips) + Expect(err).NotTo(HaveOccurred(), "Should marshal IPs for annotation") + + // Define the Pod object with the specified annotation + By("Creating the pod with the default network annotation and wait for readiness") + pod := e2epod.NewAgnhostPod(f.Namespace.Name, "static-ip-mac-pod", nil, nil, nil) + pod.Annotations = map[string]string{ + "v1.multus-cni.io/default-network": fmt.Sprintf(`[{"name":"default", "namespace":"ovn-kubernetes", "mac":%q, "ips": %s}]`, tc.mac, string(ips)), + } + pod.Spec.Containers[0].Command = []string{"sleep", "infinity"} + pod = e2epod.NewPodClient(f).CreateSync(context.TODO(), pod) + + netStatus, err := podNetworkStatus(pod, func(status nadapi.NetworkStatus) bool { + return status.Default + }) + Expect(err).NotTo(HaveOccurred(), "Should get network status from pod") + Expect(netStatus).To(HaveLen(1), "Should have one network status for the default network") + var exposedIPs []string + + // Remove the CIDR from the IPs to expose only the IPs + for _, ip := range tc.ips { + exposedIPs = append(exposedIPs, strings.Split(ip, "/")[0]) + } + Expect(netStatus[0].IPs).To(ConsistOf(exposedIPs), "Should have the IPs specified in the default network annotation") + Expect(strings.ToLower(netStatus[0].Mac)).To(Equal(strings.ToLower(tc.mac)), "Should have the MAC specified in the default network annotation") + + }, + + Entry("should create the pod with the specified static IP and MAC address", testCase{ + ips: []string{"103.0.0.3/16", "2014:100:200::3/60"}, + mac: "02:A1:B2:C3:D4:E5", + }), + ) +}) From a3de8680a5a8f599a34abd710938720993c2774a Mon Sep 17 00:00:00 2001 From: Enrique Llorente Date: Fri, 1 Aug 2025 11:30:27 +0200 Subject: [PATCH 035/115] allocator, pod: Validate consistency of ipRequest and ipamClaims IPs Ensure that a pod's requested IP (via ipRequest) matches the IP provisioned by ipamClaims in its status. Failure to match should prevent pod creation, as users are unable to alter a pod's requested IPs once set. Signed-off-by: Enrique Llorente --- .../pkg/allocator/pod/pod_annotation.go | 11 +++++++-- .../pkg/allocator/pod/pod_annotation_test.go | 23 +++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/go-controller/pkg/allocator/pod/pod_annotation.go b/go-controller/pkg/allocator/pod/pod_annotation.go index cca6761845..31164d3a7c 100644 --- a/go-controller/pkg/allocator/pod/pod_annotation.go +++ b/go-controller/pkg/allocator/pod/pod_annotation.go @@ -208,7 +208,7 @@ func allocatePodAnnotationWithTunnelID( } // validateStaticIPRequest checks if a static IP request can be honored when IPAM is enabled for the given network. -func validateStaticIPRequest(netInfo util.NetInfo, podDesc string) error { +func validateStaticIPRequest(netInfo util.NetInfo, network *nadapi.NetworkSelectionElement, ipamClaim *ipamclaimsapi.IPAMClaim, podDesc string) error { // Allow static IPs with IPAM only for primary networks with layer2 topology when EnablePreconfiguredUDNAddresses is enabled // Feature gate integration: EnablePreconfiguredUDNAddresses controls static IP allocation with IPAM if !util.IsPreconfiguredUDNAddressesEnabled() { @@ -226,6 +226,13 @@ func validateStaticIPRequest(netInfo util.NetInfo, podDesc string) error { // requests when IPAM is enabled. return fmt.Errorf("cannot allocate a static IP request with IPAM for pod %s: layer2 topology is required, but network has topology %q", podDesc, netInfo.TopologyType()) } + if ipamClaim != nil && len(ipamClaim.Status.IPs) > 0 { + for _, ipRequest := range network.IPRequest { + if !util.IsItemInSlice(ipamClaim.Status.IPs, ipRequest) { + return fmt.Errorf("cannot allocate a static IP request with IPAM for pod %q: the pod references an ipam claim with IPs not containing the requested IP %q", podDesc, ipRequest) + } + } + } return nil } @@ -354,7 +361,7 @@ func allocatePodAnnotationWithRollback( } if hasIPAM && hasStaticIPRequest { - if err = validateStaticIPRequest(netInfo, podDesc); err != nil { + if err = validateStaticIPRequest(netInfo, network, ipamClaim, podDesc); err != nil { return } } diff --git a/go-controller/pkg/allocator/pod/pod_annotation_test.go b/go-controller/pkg/allocator/pod/pod_annotation_test.go index a01a8f7bcd..946ca79070 100644 --- a/go-controller/pkg/allocator/pod/pod_annotation_test.go +++ b/go-controller/pkg/allocator/pod/pod_annotation_test.go @@ -658,6 +658,29 @@ func Test_allocatePodAnnotationWithRollback(t *testing.T) { }, wantErr: true, }, + { + // on networks with IPAM and layer2 topology, expect error when IPAMClaims status IPs do not match requested IPs + name: "expect error, static IP with IPAM on layer2 when IPAMClaims status IPs do not match requested IPs", + ipam: true, + role: types.NetworkRolePrimary, + persistentIPAllocation: true, + enablePreconfiguredUDNAddresses: true, + args: args{ + network: &nadapi.NetworkSelectionElement{ + IPRequest: []string{"192.168.0.101/24"}, + IPAMClaimReference: "my-ipam-claim", + }, + ipamClaim: &ipamclaimsapi.IPAMClaim{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-ipam-claim", + }, + Status: ipamclaimsapi.IPAMClaimStatus{ + IPs: []string{"192.168.0.200/24"}, + }, + }, + }, + wantErr: true, + }, { // with preconfigured UDN address feature enabled still continue failing with secondary layer2 with ipam + static IPs name: "expect error, static IP with IPAM on secondary network when EnablePreconfiguredUDNAddresses is enabled", From d49c46c030a6dd54d879e2da9143815fc290c80a Mon Sep 17 00:00:00 2001 From: Enrique Llorente Date: Fri, 1 Aug 2025 13:17:49 +0200 Subject: [PATCH 036/115] gh, actions: Add multihoming + net-seg + static IPs to test workflow This commit adds the necessary configurations to the GitHub Actions workflow to test multihoming, network segmentation, and static IPs. It includes changes to the test.yml file to enable these tests. Signed-off-by: Enrique Llorente --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 516dec2f43..cd0a35e4c3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -467,7 +467,7 @@ jobs: - {"target": "node-ip-mac-migration", "ha": "noHA", "gateway-mode": "shared", "ipfamily": "ipv6", "disable-snat-multiple-gws": "SnatGW", "second-bridge": "1br", "ic": "ic-disabled"} - {"target": "node-ip-mac-migration", "ha": "noHA", "gateway-mode": "shared", "ipfamily": "ipv4", "disable-snat-multiple-gws": "SnatGW", "second-bridge": "1br", "ic": "ic-single-node-zones"} - {"target": "compact-mode", "ha": "noHA", "gateway-mode": "local", "ipfamily": "ipv4", "disable-snat-multiple-gws": "snatGW", "second-bridge": "1br", "ic": "ic-disabled"} - - {"target": "multi-homing", "ha": "noHA", "gateway-mode": "local", "ipfamily": "dualstack", "disable-snat-multiple-gws": "SnatGW", "second-bridge": "1br", "ic": "ic-single-node-zones"} + - {"target": "multi-homing", "ha": "noHA", "gateway-mode": "local", "ipfamily": "dualstack", "disable-snat-multiple-gws": "SnatGW", "second-bridge": "1br", "ic": "ic-single-node-zones", "network-segmentation": "enable-network-segmentation"} - {"target": "multi-node-zones", "ha": "noHA", "gateway-mode": "local", "ipfamily": "ipv4", "disable-snat-multiple-gws": "SnatGW", "second-bridge": "1br", "ic": "ic-multi-node-zones", "num-workers": "3", "num-nodes-per-zone": "2"} - {"target": "external-gateway", "ha": "noHA", "gateway-mode": "shared", "ipfamily": "ipv4", "disable-snat-multiple-gws": "noSnatGW", "second-bridge": "2br", "ic": "ic-single-node-zones"} - {"target": "external-gateway", "ha": "noHA", "gateway-mode": "local", "ipfamily": "ipv4", "disable-snat-multiple-gws": "noSnatGW", "second-bridge": "1br", "ic": "ic-single-node-zones"} @@ -513,7 +513,7 @@ jobs: TRAFFIC_FLOW_TESTS: "${{ matrix.traffic-flow-tests }}" ENABLE_ROUTE_ADVERTISEMENTS: "${{ matrix.routeadvertisements != '' }}" ADVERTISE_DEFAULT_NETWORK: "${{ matrix.routeadvertisements == 'advertise-default' }}" - ENABLE_PRE_CONF_UDN_ADDR: "${{ ( matrix.target == 'network-segmentation' || matrix.target == 'kv-live-migration' ) && matrix.ic == 'ic-single-node-zones' }}" + ENABLE_PRE_CONF_UDN_ADDR: "${{ ( ( matrix.target == 'multi-homing' && matrix.network-segmentation == 'enable-network-segmentation' ) || matrix.target == 'kv-live-migration' ) && matrix.ic == 'ic-single-node-zones' }}" steps: - name: Install VRF kernel module From c0fad85f2931a070b318a9b02913046e138e4769 Mon Sep 17 00:00:00 2001 From: Periyasamy Palanisamy Date: Tue, 29 Jul 2025 07:09:29 +0530 Subject: [PATCH 037/115] Remove NetworkUnavailable condition from node The NodeNetworkUnavailable condition can be set after ovn-k processed the node successfully so we cannot do the early exit without checking for this. Order of events: 1. Node is added without the NodeNetworkUnavailable condition 2. OVN-Kubernetes reconciles the node 3. Condition is added by an external entity 4. We never remove it because we exit early Hence this commit adds NodeNetworkUnavailable condition check for node update event and ensures h.clearInitialNodeNetworkUnavailableCondition method is called at least once to clear this condition. Signed-off-by: Periyasamy Palanisamy --- .../pkg/clustermanager/network_cluster_controller.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/go-controller/pkg/clustermanager/network_cluster_controller.go b/go-controller/pkg/clustermanager/network_cluster_controller.go index ef2ac665ae..f31e9ec8aa 100644 --- a/go-controller/pkg/clustermanager/network_cluster_controller.go +++ b/go-controller/pkg/clustermanager/network_cluster_controller.go @@ -16,6 +16,7 @@ import ( cache "k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/record" "k8s.io/client-go/util/retry" + k8snodeutil "k8s.io/component-helpers/node/util" "k8s.io/klog/v2" "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/allocator/id" @@ -576,7 +577,10 @@ func (h *networkClusterControllerEventHandler) UpdateResource(oldObj, newObj int // 1. we missed an add event (bug in kapi informer code) // 2. a user removed the annotation on the node // Either way to play it safe for now do a partial json unmarshal check - if !nodeFailed && util.NoHostSubnet(oldNode) == util.NoHostSubnet(newNode) && !h.ncc.nodeAllocator.NeedsNodeAllocation(newNode) { + _, nodeCondition := k8snodeutil.GetNodeCondition(&newNode.Status, corev1.NodeNetworkUnavailable) + nodeNetworkUnavailable := nodeCondition != nil && nodeCondition.Status == corev1.ConditionTrue + if !nodeFailed && util.NoHostSubnet(oldNode) == util.NoHostSubnet(newNode) && + !h.ncc.nodeAllocator.NeedsNodeAllocation(newNode) && !nodeNetworkUnavailable { // no other node updates would require us to reconcile again return nil } From eaf91a72d591bfbdc228b8490de8f404d378f779 Mon Sep 17 00:00:00 2001 From: Yun Zhou Date: Fri, 1 Aug 2025 17:33:18 -0700 Subject: [PATCH 038/115] fix flow update error Recent commit fd5e79154 reintroduce the flow update error that was fixed by commit 00542735: when gateway accelerated interface is used. When gateway accelerated interface is used, we noticed the error messages 'gateway_shared_intf.go:392] Unable to get port list from bridge. ... failed to get list of ports on bridge "enp1s0f0v0":, stderr: "ovs-ofctl: enp1s0f0v0 is not a bridge or a socket\n" ...'. Signed-off-by: Yun Zhou --- go-controller/pkg/node/gateway_shared_intf.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go-controller/pkg/node/gateway_shared_intf.go b/go-controller/pkg/node/gateway_shared_intf.go index d60783144c..0fdfe229ff 100644 --- a/go-controller/pkg/node/gateway_shared_intf.go +++ b/go-controller/pkg/node/gateway_shared_intf.go @@ -368,7 +368,7 @@ func (npw *nodePortWatcher) updateServiceFlowCache(service *corev1.Service, netI var ofPorts []string // don't get the ports unless we need to as it is a costly operation if (len(extParsedIPs) > 0 || len(ingParsedIPs) > 0) && add { - ofPorts, err = util.GetOpenFlowPorts(npw.gwBridge.GetGatewayIface(), false) + ofPorts, err = util.GetOpenFlowPorts(npw.gwBridge.GetBridgeName(), false) if err != nil { // in the odd case that getting all ports from the bridge should not work, // simply output to LOCAL (this should work well in the vast majority of cases, anyway) From 94944843516cbd21a2ed7ba1e2df59b6c8f95cfd Mon Sep 17 00:00:00 2001 From: Tullio Sebastiani Date: Mon, 4 Aug 2025 11:12:50 +0200 Subject: [PATCH 039/115] fixes fedora image build script Signed-off-by: Tullio Sebastiani --- dist/images/Dockerfile.fedora | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/images/Dockerfile.fedora b/dist/images/Dockerfile.fedora index fc42191887..c60e89921d 100644 --- a/dist/images/Dockerfile.fedora +++ b/dist/images/Dockerfile.fedora @@ -93,7 +93,7 @@ RUN echo "Running on $BUILDPLATFORM, building for $TARGETPLATFORM" # Final stage RUN dnf install --best --refresh -y --setopt=tsflags=nodocs koji -RUN if [ "$TARGETPLATFORM" = "linux/amd64" ] || [ -z "$TARGETPLATFORM"] ; then koji download-build $ovnver --arch=x86_64 ; \ +RUN if [ "$TARGETPLATFORM" = "linux/amd64" ] || [ -z "$TARGETPLATFORM" ] ; then koji download-build $ovnver --arch=x86_64 ; \ else koji download-build $ovnver --arch=aarch64 ; fi ###################################### From e18ed9aee3c1f56998c3f6ad4d147632d5da7a02 Mon Sep 17 00:00:00 2001 From: Ihar Hrachyshka Date: Mon, 4 Aug 2025 11:15:10 -0400 Subject: [PATCH 040/115] docs: remove dead link to topology google document Fixes #5328 Signed-off-by: Ihar Hrachyshka --- docs/design/topology.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs/design/topology.md b/docs/design/topology.md index 36dc78b3e1..d3353a4487 100644 --- a/docs/design/topology.md +++ b/docs/design/topology.md @@ -66,7 +66,3 @@ It is distributed across the nodes in the cluster and is responsible for routing traffic between the different zones. FIXME: This page is lazily written, there is so much more to do here. - -## References - -* https://docs.google.com/presentation/d/1BtkYAO30gI3v6ah2hS6XTGtt6JBHNRHh64vhGEtfLEM/edit#slide=id.gfb215b3717_0_3299 \ No newline at end of file From a5b979944f04ed4b56be753c6c24e0f635349fb3 Mon Sep 17 00:00:00 2001 From: Ihar Hrachyshka Date: Tue, 5 Aug 2025 17:29:56 +0000 Subject: [PATCH 041/115] kind.sh: Don't build go-controller twice make fedora-image target already depends on go-controller. We are wasting cycles building the same thing twice. Signed-off-by: Ihar Hrachyshka --- contrib/kind.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/contrib/kind.sh b/contrib/kind.sh index af1c0f537c..8fbdbbebdf 100755 --- a/contrib/kind.sh +++ b/contrib/kind.sh @@ -858,9 +858,6 @@ build_ovn_image() { if [ "$OVN_IMAGE" == local ]; then set_ovn_image - # Build binaries - make -C ${DIR}/../go-controller - # Build image make -C ${DIR}/../dist/images IMAGE="${OVN_IMAGE}" OVN_REPO="${OVN_REPO}" OVN_GITREF="${OVN_GITREF}" OCI_BIN="${OCI_BIN}" fedora-image From bd7ebabf650bda47d47ec396d2f3dde09f78eec6 Mon Sep 17 00:00:00 2001 From: Surya Seetharaman Date: Fri, 27 Jun 2025 08:37:01 +0200 Subject: [PATCH 042/115] Add UDN user facing docs Signed-off-by: Surya Seetharaman --- .../mirrored-endpointslices.md | 135 ---- .../images/KubeletHealthchecks-Part1.png | Bin 0 -> 36819 bytes .../images/KubeletHealthchecks-Part2.png | Bin 0 -> 56072 bytes .../images/L2DeepDive-2segments.png | Bin 0 -> 190174 bytes .../images/L3DeepDive.png | Bin 0 -> 212259 bytes .../images/Layer2VMMigration.png | Bin 0 -> 70570 bytes .../images/localnet-topology.png | Bin 0 -> 102401 bytes .../images/native-namespace-isolation.png | Bin 0 -> 296503 bytes .../images/overlappingpodIPs.png | Bin 0 -> 166785 bytes .../images/tenant-isolation-lighter.png | Bin 0 -> 345958 bytes .../user-defined-networks.md | 692 ++++++++++++++++++ mkdocs.yml | 2 + 12 files changed, 694 insertions(+), 135 deletions(-) delete mode 100644 docs/features/multiple-networks/mirrored-endpointslices.md create mode 100644 docs/features/user-defined-networks/images/KubeletHealthchecks-Part1.png create mode 100644 docs/features/user-defined-networks/images/KubeletHealthchecks-Part2.png create mode 100644 docs/features/user-defined-networks/images/L2DeepDive-2segments.png create mode 100644 docs/features/user-defined-networks/images/L3DeepDive.png create mode 100644 docs/features/user-defined-networks/images/Layer2VMMigration.png create mode 100644 docs/features/user-defined-networks/images/localnet-topology.png create mode 100644 docs/features/user-defined-networks/images/native-namespace-isolation.png create mode 100644 docs/features/user-defined-networks/images/overlappingpodIPs.png create mode 100644 docs/features/user-defined-networks/images/tenant-isolation-lighter.png create mode 100644 docs/features/user-defined-networks/user-defined-networks.md diff --git a/docs/features/multiple-networks/mirrored-endpointslices.md b/docs/features/multiple-networks/mirrored-endpointslices.md deleted file mode 100644 index 39f8615779..0000000000 --- a/docs/features/multiple-networks/mirrored-endpointslices.md +++ /dev/null @@ -1,135 +0,0 @@ -# EndpointSlices mirror controller for User-Defined Networks - -## Summary - -Pods that use a [user-defined network](https://github.com/trozet/enhancements/blob/multiple_networks/enhancements/network/user-defined-network-segmentation.md) as their primary network will still have the cluster default network IP in their status. For services this results in the EndpointSlices providing the IPs of the cluster default network in the Kubernetes API. To enable services support for primary user-defined networks, the EndpointSlices mirror controller was introduced to create custom EndpointSlices with user-defined network IP addresses extracted from OVN-Kubernetes annotations. - -## Implementation - -The introduced controller duplicates the default EndpointSlices, creating new copies that include IP addresses from primary user-defined network. It bypasses EndpointSlices in namespaces that do not have a user-defined primary network. The controller lacks specific logic for selecting endpoints, it only replicates those generated by the default controller and replaces the IP addresses. For host-networked pods, the controller retains the same IP addresses as the default controller. Custom EndpointSlices not created by the default controller are not processed. - -The default EndpointSlices controller creates objects that contain the following labels: - -- `endpointslice.kubernetes.io/managed-by:endpointslice-controller.k8s.io` - Indicates that the EndpointSlice is managed by the default Kubernetes EndpointSlice controller. -- `kubernetes.io/service-name:` - The service that this EndpointSlice belongs to, used by the default network service controller. - -The EndpointSlices mirror controller uses a separate set of labels: - -- `endpointslice.kubernetes.io/managed-by:endpointslice-mirror-controller.k8s.ovn.org` - Indicates that the EndpointSlice is managed by the mirror controller. -- `k8s.ovn.org/service-name:` - The service that this mirrored EndpointSlice belongs to, used by the user-defined network service controller. Note that the label key is different from the default EndpointSlice. -- `k8s.ovn.org/source-endpointslice-version:` - The last reconciled resource version from the default EndpointSlice. - -and annotations (Label values have a length limit of 63 characters): -- `k8s.ovn.org/endpointslice-network:` - The user-defined network that the IP addresses in the mirrored EndpointSlice belong to. -- `k8s.ovn.org/source-endpointslice:` - The name of the default EndpointSlice that was the source of the mirrored EndpointSlice. - - -### Example - -With the following NetworkAttachmentDefinition: - -```yaml -apiVersion: k8s.cni.cncf.io/v1 -kind: NetworkAttachmentDefinition -metadata: - name: l3-network - namespace: nad-l3 -spec: - config: |2 - { - "cniVersion": "1.0.0", - "name": "l3-network", - "type": "ovn-k8s-cni-overlay", - "topology":"layer3", - "subnets": "10.128.0.0/16/24", - "mtu": 1300, - "netAttachDefName": "nad-l3/l3-network", - "role": "primary" - } -``` - -We can observe the following EndpointSlices created for a one-replica deployment exposed through a `sample-deployment` service: - - - - - - - - - -
Default EndpointSliceMirrored EndpointSlice
- -```yaml -kind: EndpointSlice -apiVersion: discovery.k8s.io/v1 -metadata: - name: sample-deployment-rkk4n - generateName: sample-deployment- - generation: 1 - labels: - app: l3pod - endpointslice.kubernetes.io/managed-by: endpointslice-controller.k8s.io - kubernetes.io/service-name: sample-deployment - name: sample-deployment-rkk4n - namespace: nad-l3 - resourceVersion: "31533" -addressType: IPv4 -endpoints: -- addresses: - - 10.244.1.17 - conditions: - ready: true - serving: true - terminating: false - nodeName: ovn-worker - targetRef: - kind: Pod - name: sample-deployment-6b64bd4868-7ftt6 - namespace: nad-l3 - uid: 6eb5d05c-cff4-467d-bc1b-890443750463 -ports: -- name: "" - port: 80 - protocol: TCP -``` - - - -```yaml -kind: EndpointSlice -apiVersion: discovery.k8s.io/v1 -metadata: - name: l3-network-sample-deployment-hgkmw - generateName: l3-network-sample-deployment- - labels: - endpointslice.kubernetes.io/managed-by: endpointslice-mirror-controller.k8s.ovn.org - k8s.ovn.org/service-name: sample-deployment - k8s.ovn.org/source-endpointslice-version: "31533" - annotations: - k8s.ovn.org/endpointslice-network: l3-network - k8s.ovn.org/source-endpointslice: sample-deployment-rkk4n - namespace: nad-l3 - resourceVersion: "31535" -addressType: IPv4 -endpoints: -- addresses: - - 10.128.1.3 - conditions: - ready: true - serving: true - terminating: false - nodeName: ovn-worker - targetRef: - kind: Pod - name: sample-deployment-6b64bd4868-7ftt6 - namespace: nad-l3 - uid: 6eb5d05c-cff4-467d-bc1b-890443750463 -ports: -- name: "" - port: 80 - protocol: TCP - -``` - -
diff --git a/docs/features/user-defined-networks/images/KubeletHealthchecks-Part1.png b/docs/features/user-defined-networks/images/KubeletHealthchecks-Part1.png new file mode 100644 index 0000000000000000000000000000000000000000..4ca1233bc74da2f95c670ee4de43ce75b178cc8d GIT binary patch literal 36819 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 DMSW7| literal 0 HcmV?d00001 diff --git a/docs/features/user-defined-networks/images/L2DeepDive-2segments.png b/docs/features/user-defined-networks/images/L2DeepDive-2segments.png new file mode 100644 index 0000000000000000000000000000000000000000..b04dda3f11cce9018782b22a589f97afbad01385 GIT binary patch literal 190174 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

Q=X#h+1O7Y8jQnO4WyErpvD<| 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%0A{ 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%0DdV6d~j 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

369K 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�}|2Zu*>i`m6ed6rC|>)~2x6p{y$3 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 ON@$MY;%RS=F(%LR9|KM7rC$WH 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 CQY^** literal 0 HcmV?d00001 diff --git a/docs/features/user-defined-networks/images/localnet-topology.png b/docs/features/user-defined-networks/images/localnet-topology.png new file mode 100644 index 0000000000000000000000000000000000000000..9d3782ca51f0554c63f67883bf055de7a89891ea GIT binary patch literal 102401 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%0A4%>Kxl>0^$am4Br2dyX?i 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 literal 0 HcmV?d00001 diff --git a/docs/features/user-defined-networks/images/native-namespace-isolation.png b/docs/features/user-defined-networks/images/native-namespace-isolation.png new file mode 100644 index 0000000000000000000000000000000000000000..adeb18d565e87e431f3f0d8030df6483d1531619 GIT binary patch literal 296503 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 U!8Zw3xbl;R%=OAo)MS9RDtDV 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 MSASM5YZm%{0L;F}N&o-= literal 0 HcmV?d00001 diff --git a/docs/features/user-defined-networks/images/overlappingpodIPs.png b/docs/features/user-defined-networks/images/overlappingpodIPs.png new file mode 100644 index 0000000000000000000000000000000000000000..be29b670924a5df603b9d2480bb75b2525b77688 GIT binary patch literal 166785 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 literal 0 HcmV?d00001 diff --git a/docs/features/user-defined-networks/images/tenant-isolation-lighter.png b/docs/features/user-defined-networks/images/tenant-isolation-lighter.png new file mode 100644 index 0000000000000000000000000000000000000000..11cfb812bb0fb78c40ac058455caf483980b30ea GIT binary patch literal 345958 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

j#CH>ErmL4gMw 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 IY2$$Z15BJ+umAu6 literal 0 HcmV?d00001 diff --git a/docs/features/user-defined-networks/user-defined-networks.md b/docs/features/user-defined-networks/user-defined-networks.md new file mode 100644 index 0000000000..1b0393bd5e --- /dev/null +++ b/docs/features/user-defined-networks/user-defined-networks.md @@ -0,0 +1,692 @@ +# User Defined Networks + +## Introduction + +User Defined Networks (UDNs) in OVN-Kubernetes offer flexible network configurations +for users, going beyond the traditional single default network model for all pods +within a Kubernetes cluster. This feature addresses the diverse and advanced networking +requirements of various applications and use cases. + +## Motivation + +Traditional Kubernetes networking, which typically connects all pods to a default Layer3 network, +lacks the necessary flexibility for many modern use cases and advanced network capabilities. +UDNs provide several key advantages: + +* **Workload/Tenant Isolation**: UDNs enable the grouping of different application +types into isolated networks within the cluster, preventing communication between them. +* **Flexible Network Topologies**: Users can create different types of overlay networks +that suits their use cases and then attach their workloads to these networks which are +then isolated natively. +* **Overlapping Pod IPs**: UDNs allow the creation of multiple networks within a cluster that +can use the same IP address ranges for pods, expanding deployment scenarios. + +See the [enhancement] for more details. + +[enhancement]: https://ovn-kubernetes.io/okeps/okep-5193-user-defined-networks/ + +### User-Stories/Use-Cases + +See the [user-stories] defined in the enhancement. + +[user-stories]: https://ovn-kubernetes.io/okeps/okep-5193-user-defined-networks/#user-storiesuse-cases + +The two main user stories are: + +#### Native Namespace Isolation using Networks + +![namespace-isolation](images/native-namespace-isolation.png) +Here the blue, green, purple and yellow networks within those +namespaces cannot reach other and hence provide native isolation +to the workloads in those networks from workloads in other networks. + +#### Native Tenant Isolation using Networks + +![tenant-isolation](images/tenant-isolation-lighter.png) +Here the tenants BERLIN and MUNICH are isolated from each other. +So the workloads in namespaces belonging to BERLIN across the +four namespaces - purple, yellow, green and blue can talk to each other +but they can't talk to the workloads belogning to MUNICH tenant +across namespaces brown, cyan, orange and violet. + +There are more user stories which will be covered in the sections below +with appropriate diagrams. + +## How to enable this feature on an OVN-Kubernetes cluster? + +This feature is enabled by default on all OVN-Kubernetes clusters. +You don't need to do anything extra to start using this feature. +There is a Feature Config option `--enable-network-segmentation` under +`OVNKubernetesFeatureConfig` config that can be used to disable this +feature. However note that disabling the feature will not remove +existing CRs in the cluster. This feature has to be enabled along with +the flag for multiple-networks `--enable-multi-network` since UDNs +use Network Attachment Definitions as underlying implementation detail +construct and reuse the secondary network controllers. + +## Workflow Description + +A tenant consists of one or more namespaces in a cluster. Network segmentation +can be achieved by attaching 1 or more namespaces as part of same network which +are then not reachable from other namespaces in the cluster that are not part +of that network. + +## Implementation Details + +### User facing API Changes + +The implementation of UDNs introduces two new Custom Resource Definitions (CRDs) +for network creation: + +* Namespace-scoped **UserDefinedNetwork** (UDN): This CRD is for tenant owners, +allowing them to create networks within their namespace. This provides isolation +for their namespaces from other tenants' namespaces. + +* Cluster-scoped **ClusterUserDefinedNetwork** (CUDN): This CRD provides cluster +administrators with the ability to allow multiple namespaces to be part of the +same network that is then isolated from other networks. + +**NOTE**: For a namespace to be considered for UDN creation, it must be +labeled with `k8s.ovn.org/primary-user-defined-network` at the time of its +creation. This label cannot be updated later, and if absent, the namespace +will not be considered for UDN creation. + +See the [api-specification-docs] for information on each of the fields + +[api-specification-docs]: https://ovn-kubernetes.io/api-reference/userdefinednetwork-api-spec/ + +### OVN-Kubernetes Implementation Details + +`UserDefinedNetworks` is an opinionated implementation +of multi-networking in Kubernetes. There are two types of +UserDefinedNetworks: + +* `Primary`: Also known as P-UDN -> Primary UserDefinedNetwork: This means the + network will act as the primary network for the pod and all default traffic + will pass through this network except for Kubelet healthchecks which still uses + the default cluster-wide network as Kubernetes is not multi-networking aware. +* `Secondary`: Also known as S-UDN -> Secondary UserDefinedNetwork: This means the + network will act as only a secondary network for the pod and only pod traffic + that is part of the secondary network may be routed through this interface. These + types of networks have existed for a long time usually created using + `NetworkAttachmentDefinitions` API but are now more standardised using UDN CRs. + +OVN-Kubernetes currently doesn't support north-south traffic for +secondary networks and none of the core Kubernetes features like Services will work there. +Primary networks on the other hand has full support for all features as present +on cluster default network. + +UDNs can have flexible virtual network topologies to suit the use cases +of end users. Currently supported topology types for a given network include: + +**Layer3 Networks** + +`Layer3`: is a topology type wherein the pods or VMs are connected to their +node’s local router and all these routers are then connected to the distributed +switch across nodes. + * Each pod would hence get an IP from the node's subnet segment + * When in doubt which topology to use go with layer3 which is the same topology + as the cluster default network + * Can be of type `primary` or `secondary` + +Let's see how a Layer3 Network looks on the OVN layer. + +![l3-UDN](images/L3DeepDive.png) + +Here we can see a blue and green P-UDN. On node1, pod1 is part of green UDN and +pod2 is part of blue UDN. They each have a udn-0 interface that is attached to +the UDN network and a eth0 interface that is attached to the cluster default +network (grey color) which is only used for kubelet healthchecks. + +**Layer2 Networks** + +`Layer2`: is a topology type wherein the pods or VMs are all connected to the +same layer2 flat switch. + * Usually used when the applications deployed expect a layer2 type network + connection (Perhaps applications want a single broadcast domain, latency sensitive, use proprietary L2 protocols) + * Common in Virtualization world for seamless migration of the VM since + persistent IPs of the VMs can be preserved across nodes in your cluster + during live migration + * Can be of type `primary` or `secondary` + +![l2-UDN](images/L2DeepDive-2segments.png) + +Here we can see a blue and green P-UDN. On node1, pod1 is part of green UDN and +pod2 is part of blue UDN. They each have a udn-0 interface that is attached to +the UDN network and a eth0 interface that is attached to the cluster default +network (grey color) which is only used for kubelet healthchecks. + +**Localnet Networks** + +`Localnet`: is a topology type wherein the pods or VMs attached to a localnet +network on the overlay can egress to the provider’s physical network + * without SNATing to nodeIPs… preserves the podIPs + * podIPs can be on the same subnet as the provider’s VLAN + * VLAN IDs can be used to mark the traffic coming from the localnet for + isolation on provider network + * Can be of type `secondary`, it cannot be a `primary` network of a pod. + * Only `ClusterUserDefinedNetwork` supports `localnet` + +![localnet-UDN](images/localnet-topology.png) + +Here we can see blue and green S-UDN localnet networks. + +The ovnkube-cluster-manager component watches for these CR's and the controller +reacts to it by creating NADs under the hood. The ovnkube-controller watches for +the NADs and creates the required OVN logical constructs in the OVN database. +The ovnkube-node also adds the required gateway plumbing such as openflows and +VRF tables and routes to provide networking to these networks. + +### Creating UserDefinedNetworks + +Now that we understand what a UDN is, let's get handson! + +Let's create two namespaces `blue` and `green`: + +```yaml +apiVersion: v1 +kind: Namespace +metadata: + name: blue + labels: + name: blue + k8s.ovn.org/primary-user-defined-network: "" +--- +apiVersion: v1 +kind: Namespace +metadata: + name: green + labels: + name: green + k8s.ovn.org/primary-user-defined-network: "" +``` + +Sample API yaml for create two `UserDefinedNetworks` of type `Layer3` in these namespaces: + +```yaml +apiVersion: k8s.ovn.org/v1 +kind: UserDefinedNetwork +metadata: + name: blue-network + namespace: blue + labels: + name: blue + purpose: kubecon-eu-2025-demo +spec: + topology: Layer3 + layer3: + role: Primary + subnets: + - cidr: 103.103.0.0/16 + hostSubnet: 24 +--- +apiVersion: k8s.ovn.org/v1 +kind: UserDefinedNetwork +metadata: + name: green-network + namespace: green + labels: + name: green + purpose: kubecon-eu-2025-demo +spec: + topology: Layer3 + layer3: + role: Primary + subnets: + - cidr: 203.203.0.0/16 + hostSubnet: 24 +``` + +### Inspecting a UDN Pod + +Now if you create pods on these two namespaces and try to ping one pod from +the other pod, you will see that connection won't work. + +``` + $ k get pods -n blue -owide + NAME READY STATUS RESTARTS AGE IP NODE + blue 1/1 Running 0 9h 10.244.0.7 ovn-worker + blue1 1/1 Running 0 8h 10.244.1.4 ovn-worker2 + + $ k get pods -n green -owide + NAME READY STATUS RESTARTS AGE IP NODE + green 1/1 Running 0 9h 10.244.0.6 ovn-worker +``` + +NOTE: Doing kubectl get pods and describe pod will all show the default network +podIP which is not to be confused with the UDN podIPs. Remember how we said +Kubernetes is not multi-networking aware? Hence pod.Status.IPs will always +be the IPs that kubelet is aware of for healthchecks to work. + +In order to see the real UDN PodIPs, always do a describe on the pod and see +the following annotations on the pod: +``` +$ k get pod -n green green -oyaml +apiVersion: v1 +kind: Pod +metadata: + annotations: + k8s.ovn.org/pod-networks: '{"default":{"ip_addresses":["10.244.0.6/24"], + "mac_address":"0a:58:0a:f4:00:06","routes":[{"dest":"10.244.0.0/16", + "nextHop":"10.244.0.1"},{"dest":"100.64.0.0/16","nextHop":"10.244.0.1"}], + "ip_address":"10.244.0.6/24","role":"infrastructure-locked"}, + "green/green-network":{"ip_addresses":["203.203.2.5/24"], + "mac_address":"0a:58:c8:0a:02:05","gateway_ips":["203.203.2.1"], + "routes":[{"dest":"203.203.0.0/16","nextHop":"203.203.2.1"}, + {"dest":"10.96.0.0/16","nextHop":"203.203.2.1"},{"dest":"100.65.0.0/16", + "nextHop":"203.203.2.1"}],"ip_address":"203.203.2.5/24","gateway_ip":"203.203.2.1", + "role":"primary"},"green/green-secondary-network":{"ip_addresses":["100.10.1.7/24"], + "mac_address":"0a:58:64:0a:01:07","routes":[{"dest":"100.10.0.0/16", + "nextHop":"100.10.1.1"}],"ip_address":"100.10.1.7/24","role":"secondary"}}' +``` +The above shows the OVN-Kubernetes IPAM Annotation for each type of network: +* `default` which is the cluster-wide `infrastructure-locked` network only used + for Kubelet health checks and pod has IP 10.244.0.6 here +* `primary` which is the primary UDN for the pod through which all traffic + passes through and pod has IP 203.203.2.5. +* `secondary` which is the secondary UDN network for the pod from which pod has IP 100.10.1.7 + +One can also use the multus annotation to figure out the podIPs on each interface: + +``` +$ oc get pod -n green green -oyaml +apiVersion: v1 +kind: Pod +metadata: + annotations: + k8s.v1.cni.cncf.io/network-status: |- + [{ + "name": "ovn-kubernetes", + "interface": "eth0", + "ips": [ + "10.244.0.6" + ], + "mac": "0a:58:0a:f4:00:06", + "dns": {} + },{ + "name": "ovn-kubernetes", + "interface": "ovn-udn1", + "ips": [ + "200.203.2.5" + ], + "mac": "0a:58:c8:0a:02:05", + "default": true, + "dns": {} + },{ + "name": "green/green-secondary-network", + "interface": "net1", + "ips": [ + "100.10.1.7" + ], + "mac": "0a:58:64:0a:01:07", + "dns": {} + }] +``` + +### KubeletHealthChecks for UDN pods + +In each of the above diagrams we saw a grey network still attached to all +pods across all UDNs. This represents the cluster default network which +is `infrastructure-locked` for primary-UDN pods and is only used for healthchecks. + +We add UDN Isolation ACLs and cgroups NFTable rules on these pod ports so that +no traffic except healthcheck traffic from kubelet is allowed to reach these pods. + +Using OVN ACLs, we ensure only traffic from kubelet is allowed on the +default `eth0` interface of the pods: + +``` +_uuid : 1278b0f4-0a14-4637-9d05-83ba9df6ec03 +action : allow +direction : from-lport +external_ids : {direction=Egress, "k8s.ovn.org/id"="default-network-controller:UDNIsolation:AllowHostARPSecondary:Egress", "k8s.ovn.org/name"=AllowHostARPSecondary, "k8s.ovn.org/owner-controller"=default-network-controller, "k8s.ovn.org/owner-type"=UDNIsolation} +label : 0 +log : false +match : "inport == @a8747502060113802905 && (( arp && arp.tpa == 10.244.2.2 ) || ( nd && nd.target == fd00:10:244:3::2 ))" +meter : acl-logging +name : [] +options : {} +priority : 1001 +sample_est : [] +sample_new : [] +severity : [] +tier : 0 + +_uuid : 489ae95b-ae9d-47d0-bf1d-b2477a9ed6a2 +action : allow +direction : to-lport +external_ids : {direction=Ingress, "k8s.ovn.org/id"="default-network-controller:UDNIsolation:AllowHostARPSecondary:Ingress", "k8s.ovn.org/name"=AllowHostARPSecondary, "k8s.ovn.org/owner-controller"=default-network-controller, "k8s.ovn.org/owner-type"=UDNIsolation} +label : 0 +log : false +match : "outport == @a8747502060113802905 && (( arp && arp.spa == 10.244.2.2 ) || ( nd && nd.target == fd00:10:244:3::2 ))" +meter : acl-logging +name : [] +options : {} +priority : 1001 +sample_est : [] +sample_new : [] +severity : [] +tier : 0 + + +_uuid : 980be3e4-75af-45f7-bce3-3bb08ecd8b3a +action : drop +direction : to-lport +external_ids : {direction=Ingress, "k8s.ovn.org/id"="default-network-controller:UDNIsolation:DenySecondary:Ingress", "k8s.ovn.org/name"=DenySecondary, "k8s.ovn.org/owner-controller"=default-network-controller, "k8s.ovn.org/owner-type"=UDNIsolation} +label : 0 +log : false +match : "outport == @a8747502060113802905" +meter : acl-logging +name : [] +options : {} +priority : 1000 +sample_est : [] +sample_new : [] +severity : [] +tier : 0 + +_uuid : cca19dca-1fde-4a14-841d-7e2cce804de4 +action : drop +direction : from-lport +external_ids : {direction=Egress, "k8s.ovn.org/id"="default-network-controller:UDNIsolation:DenySecondary:Egress", "k8s.ovn.org/name"=DenySecondary, "k8s.ovn.org/owner-controller"=default-network-controller, "k8s.ovn.org/owner-type"=UDNIsolation} +label : 0 +log : false +match : "inport == @a8747502060113802905" +meter : acl-logging +name : [] +options : {} +priority : 1000 +sample_est : [] +sample_new : [] +severity : [] +tier : 0 +``` + +![kubelet-healthchecks-part1](images/KubeletHealthchecks-Part1.png) + +As you can see here a default network pod, `pod2` can't reach +the UDN pod `pod1` via its eth0 interface thanks to the ACLs in place. +So no traffic from the UDN pod ever leaves via `eth0`. The only traffic +that is allowed via `eth0` interface is the kubelet probe traffic. + +But given how we have allow ACLs for kubelet traffic, but this matches +on management portIP which is the hostIP, any process on the host can +potentially reach the UDN pods. In order to have more tighter security, +we have cgroups based NFT rules on the host to prevent any non-kubelet +process from being able to reach the default network `eth0` port on +UDN pods. + +![kubelet-healthchecks-part2](images/KubeletHealthchecks-Part2.png) + +These rules look like this: + +``` + chain udn-isolation { + comment "Host isolation for user defined networks" + type filter hook output priority filter; policy accept; + ip daddr . meta l4proto . th dport @udn-open-ports-v4 accept + ip daddr @udn-open-ports-icmp-v4 meta l4proto icmp accept + socket cgroupv2 level 2 475436 ip daddr @udn-pod-default-ips-v4 accept + ip daddr @udn-pod-default-ips-v4 drop + ip6 daddr . meta l4proto . th dport @udn-open-ports-v6 accept + ip6 daddr @udn-open-ports-icmp-v6 meta l4proto ipv6-icmp accept + socket cgroupv2 level 2 475436 ip6 daddr @udn-pod-default-ips-v6 accept + ip6 daddr @udn-pod-default-ips-v6 drop + } + + set udn-open-ports-v4 { + type ipv4_addr . inet_proto . inet_service + comment "default network open ports of pods in user defined networks (IPv4)" + } + + set udn-open-ports-v6 { + type ipv6_addr . inet_proto . inet_service + comment "default network open ports of pods in user defined networks (IPv6)" + } + + set udn-open-ports-icmp-v4 { + type ipv4_addr + comment "default network IPs of pods in user defined networks that allow ICMP (IPv4)" + } + + set udn-open-ports-icmp-v6 { + type ipv6_addr + comment "default network IPs of pods in user defined networks that allow ICMP (IPv6)" + } + + set udn-pod-default-ips-v4 { + type ipv4_addr + comment "default network IPs of pods in user defined networks (IPv4)" + } + + set udn-pod-default-ips-v6 { + type ipv6_addr + comment "default network IPs of pods in user defined networks (IPv6)" + } +``` + +The only exception to this is when users annotate +the UDN pod using the `open-default-ports` annotation: +``` +k8s.ovn.org/open-default-ports: | + - protocol: tcp + port: 80 + - protocol: udp + port: 53 +``` +which means we open up allow ACLs and nftrules to allow traffic +to reach at those ports. + +### Overlapping PodIPs + +Two networks can have the same subnet since they are completely +isolated. We use a `masqueradeIP` SNAT per UDN to avoid conntrack +collisions on the host. So traffic leaving each UDN is SNATed to +a unique IP before being sent to the host. + +![overlapping-podips](images/overlappingpodIPs.png) + +### VM LiveMigration and PersistentIPs over Layer2 UDNs + +Users can use the `layer2` topology when creating virtual machines +on OVN-Kubernetes and can easily live migrate the VMs across nodes +along with preserving their IPs. + +![overlapping-podips](images/Layer2VMMigration.png) + +### Services on UDNs + +Creating a service on UDNs is same as creating them on default +network, no extra plumbing is required. + +```yaml +apiVersion: v1 +kind: Service +metadata: + name: service-blue + namespace: blue + labels: + network: blue +spec: + type: LoadBalancer + selector: + network: blue + ports: + - name: web + port: 80 + targetPort: 8080 +``` +``` +$ k get svc -n blue +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +service-blue LoadBalancer 10.96.207.175 172.19.0.10 80:31372/TCP 5s +$ k get endpointslice -n blue +NAME ADDRESSTYPE PORTS ENDPOINTS AGE +service-blue-55d6c IPv4 8080 103.103.1.5,103.103.0.5 65s +service-blue-pkll7 IPv4 8080 10.244.0.3,10.244.1.8 66s +``` +One set of endpoints show the UDN ntework IPs of the pods and the other set +shows default network IPs. + +When the service is created inside the blue namespace, the +clusterIPs get automatically isolated from pods in other networks. +However nodeports, loadbalancerIPs and externalIPs can be reached +across UDNs. + +### EndpointSlices mirror controller for User-Defined Networks + +Pods that use a UDN as their primary network will still have the cluster +default network IP in their status. For services this results in the EndpointSlices +providing the IPs of the cluster default network in the Kubernetes API. To enable +services support for primary user-defined networks, the EndpointSlices mirror +controller was introduced to create custom EndpointSlices with user-defined +network IP addresses extracted from OVN-Kubernetes annotations. + +The introduced controller duplicates the default EndpointSlices, creating +new copies that include IP addresses from primary user-defined network. It +bypasses EndpointSlices in namespaces that do not have a user-defined primary +network. The controller lacks specific logic for selecting endpoints, it only +replicates those generated by the default controller and replaces the IP addresses. +For host-networked pods, the controller retains the same IP addresses as the +default controller. Custom EndpointSlices not created by the default controller +are not processed. + +The default EndpointSlices controller creates objects that contain the following labels: + +- `endpointslice.kubernetes.io/managed-by:endpointslice-controller.k8s.io` - Indicates + that the EndpointSlice is managed by the default Kubernetes EndpointSlice controller. +- `kubernetes.io/service-name:` - The service that this EndpointSlice + belongs to, used by the default network service controller. + +The EndpointSlices mirror controller uses a separate set of labels: + +- `endpointslice.kubernetes.io/managed-by:endpointslice-mirror-controller.k8s.ovn.org` - Indicates + that the EndpointSlice is managed by the mirror controller. +- `k8s.ovn.org/service-name:` - The service that this mirrored EndpointSlice + belongs to, used by the user-defined network service controller. Note that the label + key is different from the default EndpointSlice. +- `k8s.ovn.org/source-endpointslice-version:` - The + last reconciled resource version from the default EndpointSlice. + +and annotations (Label values have a length limit of 63 characters): +- `k8s.ovn.org/endpointslice-network:` - The user-defined network + that the IP addresses in the mirrored EndpointSlice belong to. +- `k8s.ovn.org/source-endpointslice:` - The name of the + default EndpointSlice that was the source of the mirrored EndpointSlice. + +Example: + +With the following NetworkAttachmentDefinition: + +```yaml +apiVersion: k8s.cni.cncf.io/v1 +kind: NetworkAttachmentDefinition +metadata: + name: l3-network + namespace: nad-l3 +spec: + config: |2 + { + "cniVersion": "1.0.0", + "name": "l3-network", + "type": "ovn-k8s-cni-overlay", + "topology":"layer3", + "subnets": "10.128.0.0/16/24", + "mtu": 1300, + "netAttachDefName": "nad-l3/l3-network", + "role": "primary" + } +``` + +We can observe the following EndpointSlices created for a one-replica deployment +exposed through a `sample-deployment` service: + + + + + + + + + +
Default EndpointSliceMirrored EndpointSlice
+ +```yaml +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 +metadata: + name: sample-deployment-rkk4n + generateName: sample-deployment- + generation: 1 + labels: + app: l3pod + endpointslice.kubernetes.io/managed-by: endpointslice-controller.k8s.io + kubernetes.io/service-name: sample-deployment + name: sample-deployment-rkk4n + namespace: nad-l3 + resourceVersion: "31533" +addressType: IPv4 +endpoints: +- addresses: + - 10.244.1.17 + conditions: + ready: true + serving: true + terminating: false + nodeName: ovn-worker + targetRef: + kind: Pod + name: sample-deployment-6b64bd4868-7ftt6 + namespace: nad-l3 + uid: 6eb5d05c-cff4-467d-bc1b-890443750463 +ports: +- name: "" + port: 80 + protocol: TCP +``` + + + +```yaml +kind: EndpointSlice +apiVersion: discovery.k8s.io/v1 +metadata: + name: l3-network-sample-deployment-hgkmw + generateName: l3-network-sample-deployment- + labels: + endpointslice.kubernetes.io/managed-by: endpointslice-mirror-controller.k8s.ovn.org + k8s.ovn.org/service-name: sample-deployment + k8s.ovn.org/source-endpointslice-version: "31533" + annotations: + k8s.ovn.org/endpointslice-network: l3-network + k8s.ovn.org/source-endpointslice: sample-deployment-rkk4n + namespace: nad-l3 + resourceVersion: "31535" +addressType: IPv4 +endpoints: +- addresses: + - 10.128.1.3 + conditions: + ready: true + serving: true + terminating: false + nodeName: ovn-worker + targetRef: + kind: Pod + name: sample-deployment-6b64bd4868-7ftt6 + namespace: nad-l3 + uid: 6eb5d05c-cff4-467d-bc1b-890443750463 +ports: +- name: "" + port: 80 + protocol: TCP + +``` + +
+ +That's how behind the scenes services on UDNs are implemented. + +## References + +* Use the workshop yamls [here](https://github.com/tssurya/kubecon-eu-2025-london-udn-workshop/tree/main/manifests) to play around diff --git a/mkdocs.yml b/mkdocs.yml index f82f75c977..82ce0965e0 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -110,6 +110,8 @@ nav: - AdminPolicyBasedExternalRoutes: api-reference/admin-epbr-api-spec.md - UserDefinedNetwork: api-reference/userdefinednetwork-api-spec.md - Features: + - Universal Connectivity: + - UserDefinedNetwork: features/user-defined-networks/user-defined-network.md - NetworkSecurityControls: - AdminNetworkPolicy: features/network-security-controls/admin-network-policy.md - NetworkPolicy: features/network-security-controls/network-policy.md From dda44c8399d41d799940f2d32fd083eb0ea988e0 Mon Sep 17 00:00:00 2001 From: Patryk Diak Date: Wed, 6 Aug 2025 11:59:23 +0200 Subject: [PATCH 043/115] ovnkube: Do not exit early on ovs CLI initialization errors OVS client setup can fail if something cancels the context before it's creation during startup. If that happens it used to exit early without returning any other errors or doing any cleanup. Signed-off-by: Patryk Diak --- go-controller/cmd/ovnkube/ovnkube.go | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/go-controller/cmd/ovnkube/ovnkube.go b/go-controller/cmd/ovnkube/ovnkube.go index 8021297d14..83ef37c2d8 100644 --- a/go-controller/cmd/ovnkube/ovnkube.go +++ b/go-controller/cmd/ovnkube/ovnkube.go @@ -445,7 +445,7 @@ func runOvnKube(ctx context.Context, runMode *ovnkubeRunMode, ovnClientset *util wg := &sync.WaitGroup{} var cancel context.CancelFunc ctx, cancel = context.WithCancel(ctx) - var managerErr, controllerErr, nodeErr error + var managerErr, controllerErr, nodeErr, ovsCLIErr error if runMode.clusterManager { wg.Add(1) @@ -579,21 +579,23 @@ func runOvnKube(ctx context.Context, runMode *ovnkubeRunMode, ovnClientset *util // Note: for ovnkube node mode dpu-host no metrics is required as ovs/ovn is not running on the node. if config.OvnKubeNode.Mode != types.NodeModeDPUHost && config.Metrics.OVNMetricsBindAddress != "" { metricsScrapeInterval := 30 - defer cancel() if ovsClient == nil { ovsClient, err = libovsdb.NewOVSClient(ctx.Done()) if err != nil { - return fmt.Errorf("failed to initialize libovsdb vswitchd client: %w", err) + ovsCLIErr = fmt.Errorf("failed to initialize libovsdb vswitchd client: %w", err) + cancel() } } - if config.Metrics.ExportOVSMetrics { - metrics.RegisterOvsMetricsWithOvnMetrics(ovsClient, metricsScrapeInterval, ctx.Done()) + if ovsClient != nil { + if config.Metrics.ExportOVSMetrics { + metrics.RegisterOvsMetricsWithOvnMetrics(ovsClient, metricsScrapeInterval, ctx.Done()) + } + metrics.RegisterOvnMetrics(ovnClientset.KubeClient, runMode.identity, + ovsClient, metricsScrapeInterval, ctx.Done()) + metrics.StartOVNMetricsServer(config.Metrics.OVNMetricsBindAddress, + config.Metrics.NodeServerCert, config.Metrics.NodeServerPrivKey, ctx.Done(), wg) } - metrics.RegisterOvnMetrics(ovnClientset.KubeClient, runMode.identity, - ovsClient, metricsScrapeInterval, ctx.Done()) - metrics.StartOVNMetricsServer(config.Metrics.OVNMetricsBindAddress, - config.Metrics.NodeServerCert, config.Metrics.NodeServerPrivKey, ctx.Done(), wg) } // run until cancelled @@ -604,7 +606,7 @@ func runOvnKube(ctx context.Context, runMode *ovnkubeRunMode, ovnClientset *util wg.Wait() klog.Infof("Stopped ovnkube") - err = utilerrors.Join(managerErr, controllerErr, nodeErr) + err = utilerrors.Join(managerErr, controllerErr, nodeErr, ovsCLIErr) if err != nil { return fmt.Errorf("failed to run ovnkube: %w", err) } From 0a387dcbed64e1352c1473a2600291c6a7fc8e6f Mon Sep 17 00:00:00 2001 From: Patryk Diak Date: Tue, 5 Aug 2025 18:12:09 +0200 Subject: [PATCH 044/115] Bump OVN to 25.03.0-73.el9fdp for OCP and 25.03.1-36.el9s for OKD A list of relevant bug fixes and new core OVN features picked up by the bump: Bug fixes: ========== - logical-fields: Fix IPv6 dp flow explosion caused by ip6.mcast_rsvd. (#FDP-1557) https://issues.redhat.com/browse/FDP-1557 - controller: Slightly optimize the runtime_data handler for sb_ro. - Revert "northd: Don't skip the unSNAT stage for traffic towards VIPs." - fixes HWOL for node port traffic with NVidia NICs - controller: Install QoS rules even on 'system' ports. (#FDP-1472) https://issues.redhat.com/browse/FDP-1472 - controller: Make sure we run engine_cleanup after thread destroy. - northd: Sample_Collector.set_ids can actually be 32-bit values. New Features: ============= - Added support to choose selection methods - dp_hash or hash (with specified hash fields) for ECMP routes while choosing nexthop. - Added support for Spine-Leaf topology of logical switches by adding a new LSP type 'switch' that can directly connect two logical switches. Supported for both distributed and transit switches. - SSL/TLS: * TLSv1 and TLSv1.1 protocols are deprecated and disabled by default on OpenFlow and database connections. Use --ssl-protocols to turn them back on. Support will be fully removed in the next release. * OpenSSL 1.1.1 or newer is now required for SSL/TLS support. * The protocol list in --ssl-protocols or corresponding database column now supports specifying simple protocol ranges like: - "TLSv1-TLSv1.2" to enable all protocols between TLSv1 and TLSv1.2. - "TLSv1.2+" to enable protocol TLSv1.2 and later. The value must be a list of protocols or exactly one protocol range. * Added explicit support for TLSv1.3. It can now be enabled via --ssl-protocols (TLSv1.3 was supported in earlier versions only when this option was not set). TLS ciphersuites for TLSv1.3 and later can be configured via --ssl-ciphersuites (--ssl-ciphers only applies to TLSv1.2 and earlier). - Add "arp-nd-max-timeout-sec" config option to vswitchd external-ids to configure the interval (in seconds) between ovn-controller originated ARP/ND packets used for tracking ECMP next hop MAC addresses. - Auto flush ECMP symmetric reply connection states when an ECMP route is removed by the CMS. This behavior is controlled by the "ecmp_nexthop_monitor_enable" config option in the NB_Global table. Disabled by default. - Improved handling of IPv6 traffic by enabling address prefix tracking in OVS for both IPv4 and IPv6 addresses, whenever possible, reducing the amount of IPv6 datapath flows. - Add concept of Transit Routers, users are now allowed to specify options:requested-chassis for router ports; if the chassis is remote then the router port will behave as a remote port. - Added a new ACL option "persist-established" that allows for established connections to bypass ACL matching. This way, if an ACL match changes, traffic on the established connection can still pass. - Logical router policies can now be arranged in chains. Using the new "jump" action, combined with new "chain" and "jump_chain" columns, allows for policies to be chained together. - Dynamic Routing support (FRR BGP integration for unicast routing) - Add "options:ct-commit-all" to LR, that enables commit of all traffic to DNAT and SNAT zone when LR is stateful. Co-authored-by: Dumitru Ceara Signed-off-by: Patryk Diak --- Dockerfile.base | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile.base b/Dockerfile.base index 071f6e6a01..e6cac3158a 100644 --- a/Dockerfile.base +++ b/Dockerfile.base @@ -17,13 +17,13 @@ RUN dnf --setopt=retries=2 --setopt=timeout=2 install -y --nodocs \ # reduces the number of variables in the system) and receive all the CVE and # bug fixes automatically. ARG ovsver=3.5 -ARG ovnver=24.09.2-69.el9fdp +ARG ovnver=25.03.0-73.el9fdp # NOTE: Ensure that the versions of OVS and OVN are overriden for OKD in each of the subsequent layers. # Centos and RHEL releases for ovn are built out of sync, so please make sure to bump for OKD with # the corresponding Centos version when updating the OCP version. ARG ovsver_okd=3.5 # We are not bumping the OVN version for OKD since the FDP release is not done yet. -ARG ovnver_okd=24.09.1-10.el9s +ARG ovnver_okd=25.03.1-36.el9s RUN INSTALL_PKGS="iptables nftables" && \ source /etc/os-release && \ From 2a0cd67da918e58a95e7ee473d16ef5681b5c123 Mon Sep 17 00:00:00 2001 From: Surya Seetharaman Date: Thu, 7 Aug 2025 14:11:14 +0200 Subject: [PATCH 045/115] nit-fix: The filename point to UDN docs is wrong Signed-off-by: Surya Seetharaman --- mkdocs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkdocs.yml b/mkdocs.yml index 82ce0965e0..1dba124302 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -111,7 +111,7 @@ nav: - UserDefinedNetwork: api-reference/userdefinednetwork-api-spec.md - Features: - Universal Connectivity: - - UserDefinedNetwork: features/user-defined-networks/user-defined-network.md + - UserDefinedNetwork: features/user-defined-networks/user-defined-networks.md - NetworkSecurityControls: - AdminNetworkPolicy: features/network-security-controls/admin-network-policy.md - NetworkPolicy: features/network-security-controls/network-policy.md From b2fa79a5f50f5bfb2a448dde714dc0fc34bec568 Mon Sep 17 00:00:00 2001 From: Arti Sood Date: Tue, 5 Aug 2025 22:21:39 -0400 Subject: [PATCH 046/115] Add config file for coderabbit AI bot Signed-off-by: Arti Sood --- .coderabbit.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .coderabbit.yml diff --git a/.coderabbit.yml b/.coderabbit.yml new file mode 100644 index 0000000000..1296d048ec --- /dev/null +++ b/.coderabbit.yml @@ -0,0 +1,2 @@ +paths_ignore: + - "**/vendor/**" From b1864a4446fdb4938ce4a2c6de597ba7b0a5307f Mon Sep 17 00:00:00 2001 From: Nadia Pinaeva Date: Tue, 29 Jul 2025 18:56:00 +0200 Subject: [PATCH 047/115] [kind] Use control-plane node IP instead of DNS name. During our tests we add secondary networks to the cluster and restart ovn-k pods (e.g. on egressIP tests), which means when the pod restarts, it can get a secondary IP for the api-server connection, which is deleted at the end of the test and causes http2: client timeout, which then causes very unobvious test failures. Signed-off-by: Nadia Pinaeva --- contrib/kind-common | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/contrib/kind-common b/contrib/kind-common index 2a564dece0..bf9bc58bc7 100644 --- a/contrib/kind-common +++ b/contrib/kind-common @@ -63,12 +63,20 @@ command_exists() { detect_apiserver_url() { # Detect API_URL used for in-cluster communication # - # Despite OVN run in pod they will only obtain the VIRTUAL apiserver address - # and since OVN has to provide the connectivity to service - # it can not be bootstrapped - # - # This is the address of the node with the control-plane - API_URL=$(kind get kubeconfig --internal --name "${KIND_CLUSTER_NAME}" | grep server | awk '{ print $2 }') + # This will return apiserver address in format https://: + DNS_NAME_URL=$(kind get kubeconfig --internal --name "${KIND_CLUSTER_NAME}" | grep server | awk '{ print $2 }') + # cut https:// from the URL + CP_NODE=${DNS_NAME_URL#*//} + # cut port from the URL + CP_NODE=${CP_NODE%:*} + # find node IP address in the kind network + if [ "$PLATFORM_IPV4_SUPPORT" == false ] && [ "$PLATFORM_IPV6_SUPPORT" == true ]; then + NODE_IP="[$($OCI_BIN inspect -f '{{.NetworkSettings.Networks.kind.GlobalIPv6Address}}' $CP_NODE)]" + else + NODE_IP=$($OCI_BIN inspect -f '{{.NetworkSettings.Networks.kind.IPAddress}}' "$CP_NODE") + fi + # replace node name with node IP address + API_URL=${DNS_NAME_URL/$CP_NODE/$NODE_IP} } docker_disable_ipv6() { From afad0c8ba6a4fd759f29437224fd263048846501 Mon Sep 17 00:00:00 2001 From: Arti Sood Date: Fri, 25 Jul 2025 09:44:44 -0400 Subject: [PATCH 048/115] K8s rebase 1.33.3 > go-controller go get k8s.io/api@v0.33.3 go get k8s.io/client-go@v0.33.3 go get k8s.io/component-helpers@v0.33.3 go get k8s.io/kubernetes@v1.33.3 go get k8s.io/apiextensions-apiserver@v0.33.3 go get sigs.k8s.io/controller-runtime@v0.21.0 go get k8s.io/controller-manager@v0.33.3 go mod tidy go mod vendor make lint Fix typecheck errors by removing "k8s.io/utils/exec".Interface arg to function call NewController() in the files below pkg/node/iptables/iptables_manager.go pkg/node/controllers/egressip/egressip_test.go Fix too many arguments in call to iptables.New in pkg/node/iptables/iptables_manager.go Fix too many arguments in call to utiliptables.New in pkg/node/controllers/egressip/egressip_test.go Update golangci-lint version to 1.68.4 in test.yaml and lint.sh Fix staticcheck error in cmd/ovnkube-trace/ovnkube-trace.go to use endpointslice API instead of endpoints cmd/ovnkube-trace/ovnkube-trace.go:383:98: SA1019: corev1.EndpointSubset is deprecated: This API is deprecated in v1.33+. (staticcheck) Endpoint port processing feedback incorporation (Peri) func extractSubsetInfo(coreclient *corev1client.CoreV1Client, restconfig *rest.Config, subsets []corev1.EndpointSubset, svcInfo *SvcInfo, ovnNamespace, addressFamily string) error { Fix error message string in /go-controller/pkg/util/multi_network_test.go for test failure fmt.Errorf("error parsing Network Attachment Definition ns1/nad1: json: cannot unmarshal string into Go struct field NetConf.NetConf.ipam of type types.IPAM") > KIND K8s version for KIND to v1.33.1 ( v1.33.3 image is not yet available) Fix k8s version for KIND in .github/workflows/test.xml, contrib/kind-common, test/scripts/upgrade-ovn.sh, test/scripts/install-kind.sh, docs/ci/ci.md and docs/installation/launching-ovn-kubernetes-on-kind.md Co-Authored-By: Periyasamy Palanisamy Signed-off-by: Arti Sood --- .github/workflows/test.yml | 4 +- contrib/kind-common | 2 +- docs/ci/ci.md | 2 +- .../launching-ovn-kubernetes-on-kind.md | 6 +- .../cmd/ovnkube-trace/ovnkube-trace.go | 73 +- go-controller/go.mod | 52 +- go-controller/go.sum | 101 +- go-controller/hack/lint.sh | 2 +- .../controllers/egressip/egressip_test.go | 5 +- .../pkg/node/iptables/iptables_manager.go | 4 +- go-controller/pkg/util/multi_network_test.go | 2 +- .../vendor/github.com/blang/semver/v4/LICENSE | 22 + .../vendor/github.com/blang/semver/v4/json.go | 23 + .../github.com/blang/semver/v4/range.go | 416 + .../github.com/blang/semver/v4/semver.go | 476 + .../vendor/github.com/blang/semver/v4/sort.go | 28 + .../vendor/github.com/blang/semver/v4/sql.go | 30 + .../vendor/github.com/golang/protobuf/AUTHORS | 3 - .../github.com/golang/protobuf/CONTRIBUTORS | 3 - .../golang/protobuf/proto/buffer.go | 324 - .../golang/protobuf/proto/defaults.go | 63 - .../golang/protobuf/proto/deprecated.go | 113 - .../golang/protobuf/proto/discard.go | 58 - .../golang/protobuf/proto/extensions.go | 356 - .../golang/protobuf/proto/properties.go | 306 - .../github.com/golang/protobuf/proto/proto.go | 167 - .../golang/protobuf/proto/registry.go | 317 - .../golang/protobuf/proto/text_decode.go | 801 -- .../golang/protobuf/proto/text_encode.go | 560 - .../github.com/golang/protobuf/proto/wire.go | 78 - .../golang/protobuf/proto/wrappers.go | 34 - .../github.com/golang/protobuf/ptypes/any.go | 180 - .../golang/protobuf/ptypes/any/any.pb.go | 62 - .../github.com/golang/protobuf/ptypes/doc.go | 10 - .../golang/protobuf/ptypes/duration.go | 76 - .../protobuf/ptypes/duration/duration.pb.go | 63 - .../golang/protobuf/ptypes/timestamp.go | 112 - .../protobuf/ptypes/timestamp/timestamp.pb.go | 64 - .../gnostic-models/compiler/extensions.go | 8 +- .../gnostic-models/extensions/extension.pb.go | 96 +- .../gnostic-models/extensions/extensions.go | 6 +- .../gnostic-models/openapiv2/OpenAPIv2.pb.go | 1349 +- .../gnostic-models/openapiv3/OpenAPIv3.pb.go | 1763 +-- .../openapiv3/annotations.pb.go | 182 + .../openapiv3/annotations.proto | 56 + .../google/go-cmp/cmp/cmpopts/sort.go | 64 +- .../go-cmp/cmp/internal/function/func.go | 7 + .../github.com/google/go-cmp/cmp/options.go | 10 +- .../github.com/google/gofuzz/.travis.yml | 10 - .../github.com/google/gofuzz/CONTRIBUTING.md | 67 - .../vendor/github.com/google/gofuzz/fuzz.go | 605 - .../github.com/gorilla/websocket/README.md | 17 +- .../github.com/gorilla/websocket/client.go | 245 +- .../gorilla/websocket/compression.go | 6 +- .../github.com/gorilla/websocket/conn.go | 112 +- .../github.com/gorilla/websocket/proxy.go | 53 +- .../github.com/gorilla/websocket/server.go | 122 +- .../gorilla/websocket/tls_handshake.go | 21 - .../gorilla/websocket/tls_handshake_116.go | 21 - .../github.com/gorilla/websocket/util.go | 15 + .../gorilla/websocket/x_net_proxy.go | 473 - .../prometheus/client_golang/NOTICE | 5 - .../internal/github.com/golang/gddo}/LICENSE | 9 +- .../golang/gddo/httputil/header/header.go | 145 + .../golang/gddo/httputil/negotiate.go | 36 + .../client_golang/prometheus/collectorfunc.go | 30 + .../collectors/go_collector_latest.go | 4 +- .../client_golang/prometheus/desc.go | 15 +- .../client_golang/prometheus/go_collector.go | 55 +- .../prometheus/go_collector_latest.go | 19 +- .../client_golang/prometheus/histogram.go | 517 +- .../prometheus/internal/difflib.go | 19 +- .../internal/go_collector_options.go | 2 + .../prometheus/internal/go_runtime_metrics.go | 3 +- .../client_golang/prometheus/metric.go | 26 +- .../prometheus/process_collector.go | 56 +- .../prometheus/process_collector_darwin.go | 130 + .../process_collector_mem_cgo_darwin.c | 84 + .../process_collector_mem_cgo_darwin.go | 51 + .../process_collector_mem_nocgo_darwin.go | 39 + ....go => process_collector_not_supported.go} | 17 +- ....go => process_collector_procfsenabled.go} | 34 +- .../prometheus/process_collector_windows.go | 21 +- .../prometheus/promhttp/delegator.go | 6 + .../client_golang/prometheus/promhttp/http.go | 138 +- .../internal/compression.go} | 19 +- .../client_golang/prometheus/registry.go | 17 +- .../client_golang/prometheus/summary.go | 49 +- .../client_golang/prometheus/vec.go | 2 +- .../prometheus/common/expfmt/decode.go | 14 +- .../prometheus/common/expfmt/encode.go | 28 +- .../prometheus/common/expfmt/expfmt.go | 78 +- .../common/expfmt/openmetrics_create.go | 10 +- .../prometheus/common/expfmt/text_create.go | 4 +- .../prometheus/common/expfmt/text_parse.go | 164 +- .../prometheus/common/model/alert.go | 7 +- .../prometheus/common/model/labels.go | 27 +- .../common/model/labelset_string.go | 2 - .../common/model/labelset_string_go120.go | 39 - .../prometheus/common/model/metric.go | 78 +- .../prometheus/common/model/silence.go | 17 +- .../prometheus/common/model/value_float.go | 3 +- .../common/model/value_histogram.go | 7 +- .../testify/assert/assertion_compare.go | 35 +- .../testify/assert/assertion_format.go | 34 +- .../testify/assert/assertion_forward.go | 68 +- .../testify/assert/assertion_order.go | 10 +- .../stretchr/testify/assert/assertions.go | 157 +- .../testify/assert/yaml/yaml_custom.go | 25 + .../testify/assert/yaml/yaml_default.go | 37 + .../stretchr/testify/assert/yaml/yaml_fail.go | 18 + .../github.com/stretchr/testify/mock/mock.go | 155 +- .../stretchr/testify/require/require.go | 432 +- .../stretchr/testify/require/require.go.tmpl | 2 +- .../testify/require/require_forward.go | 68 +- .../stretchr/testify/require/requirements.go | 2 +- .../vendor/go.opentelemetry.io/otel/LICENSE | 201 + .../otel/attribute/README.md | 3 + .../go.opentelemetry.io/otel/attribute/doc.go | 5 + .../otel/attribute/encoder.go | 135 + .../otel/attribute/filter.go | 49 + .../otel/attribute/iterator.go | 150 + .../go.opentelemetry.io/otel/attribute/key.go | 123 + .../go.opentelemetry.io/otel/attribute/kv.go | 75 + .../go.opentelemetry.io/otel/attribute/set.go | 411 + .../otel/attribute/type_string.go | 31 + .../otel/attribute/value.go | 271 + .../go.opentelemetry.io/otel/codes/README.md | 3 + .../go.opentelemetry.io/otel/codes/codes.go | 106 + .../go.opentelemetry.io/otel/codes/doc.go | 10 + .../otel/internal/attribute/attribute.go | 96 + .../go.opentelemetry.io/otel/internal/gen.go | 18 + .../otel/internal/rawhelpers.go | 48 + .../go.opentelemetry.io/otel/trace/LICENSE | 201 + .../go.opentelemetry.io/otel/trace/README.md | 3 + .../go.opentelemetry.io/otel/trace/config.go | 323 + .../go.opentelemetry.io/otel/trace/context.go | 50 + .../go.opentelemetry.io/otel/trace/doc.go | 119 + .../otel/trace/embedded/README.md | 3 + .../otel/trace/embedded/embedded.go | 45 + .../otel/trace/nonrecording.go | 16 + .../go.opentelemetry.io/otel/trace/noop.go | 85 + .../otel/trace/provider.go | 59 + .../go.opentelemetry.io/otel/trace/span.go | 177 + .../go.opentelemetry.io/otel/trace/trace.go | 323 + .../go.opentelemetry.io/otel/trace/tracer.go | 37 + .../otel/trace/tracestate.go | 330 + .../google.golang.org/grpc/CONTRIBUTING.md | 16 +- .../google.golang.org/grpc/MAINTAINERS.md | 33 +- .../vendor/google.golang.org/grpc/SECURITY.md | 2 +- .../google.golang.org/grpc/backoff/backoff.go | 2 +- .../grpc/balancer/balancer.go | 36 +- .../grpc/balancer/base/balancer.go | 6 +- .../balancer/pickfirst/internal/internal.go | 24 + .../grpc/balancer/pickfirst/pickfirst.go | 18 +- .../pickfirst/pickfirstleaf/pickfirstleaf.go | 625 + .../grpc/balancer_wrapper.go | 78 +- .../grpc_binarylog_v1/binarylog.pb.go | 24 +- .../google.golang.org/grpc/clientconn.go | 134 +- .../vendor/google.golang.org/grpc/codec.go | 69 +- .../grpc/credentials/insecure/insecure.go | 2 +- .../google.golang.org/grpc/credentials/tls.go | 29 +- .../tls/certprovider/pemfile/builder.go | 1 + .../credentials/tls/certprovider/store.go | 2 +- .../google.golang.org/grpc/dialoptions.go | 31 +- .../vendor/google.golang.org/grpc/doc.go | 2 +- .../grpc/encoding/encoding.go | 5 +- .../grpc/encoding/encoding_v2.go | 81 + .../grpc/encoding/proto/proto.go | 44 +- .../grpc/experimental/stats/metricregistry.go | 269 + .../grpc/experimental/stats/metrics.go | 114 + .../grpc/grpclog/component.go | 10 +- .../google.golang.org/grpc/grpclog/grpclog.go | 104 +- .../grpc/grpclog/internal/grpclog.go | 26 + .../grpc/grpclog/internal/logger.go | 87 + .../internal/loggerv2.go} | 178 +- .../google.golang.org/grpc/grpclog/logger.go | 59 +- .../grpc/grpclog/loggerv2.go | 181 +- .../balancer/gracefulswitch/config.go | 2 + .../grpc/internal/binarylog/method_logger.go | 2 +- .../grpc/internal/channelz/channel.go | 15 + .../grpc/internal/channelz/channelmap.go | 9 +- .../grpc/internal/channelz/funcs.go | 2 +- .../grpc/internal/channelz/server.go | 2 + .../grpc/internal/channelz/socket.go | 7 + .../grpc/internal/channelz/subchannel.go | 2 + .../internal/channelz/syscall_nonlinux.go | 4 +- .../grpc/internal/channelz/trace.go | 19 +- .../grpc/internal/envconfig/envconfig.go | 11 +- .../grpc/internal/experimental.go | 8 +- .../{prefixLogger.go => prefix_logger.go} | 40 +- .../internal/grpcsync/callback_serializer.go | 24 +- .../grpc/internal/grpcsync/pubsub.go | 4 +- .../grpc/internal/grpcutil/method.go | 2 +- .../grpc/internal/idle/idle.go | 4 +- .../grpc/internal/internal.go | 30 +- .../internal/resolver/dns/dns_resolver.go | 6 +- .../resolver/passthrough/passthrough.go | 2 +- .../grpc/internal/stats/labels.go | 42 + .../internal/stats/metrics_recorder_list.go | 105 + .../grpc/internal/status/status.go | 39 +- .../grpc/internal/syscall/syscall_nonlinux.go | 6 +- .../grpc/internal/tcp_keepalive_unix.go | 2 +- .../grpc/internal/tcp_keepalive_windows.go | 2 +- .../grpc/internal/transport/controlbuf.go | 256 +- .../grpc/internal/transport/handler_server.go | 47 +- .../grpc/internal/transport/http2_client.go | 135 +- .../grpc/internal/transport/http2_server.go | 49 +- .../grpc/internal/transport/http_util.go | 24 +- .../grpc/internal/transport/proxy.go | 10 +- .../grpc/internal/transport/transport.go | 249 +- .../grpc/keepalive/keepalive.go | 20 +- .../google.golang.org/grpc/mem/buffer_pool.go | 194 + .../grpc/mem/buffer_slice.go | 226 + .../google.golang.org/grpc/mem/buffers.go | 268 + .../grpc/metadata/metadata.go | 7 +- .../google.golang.org/grpc/preloader.go | 28 +- .../google.golang.org/grpc/regenerate.sh | 123 - .../grpc/resolver_wrapper.go | 9 +- .../vendor/google.golang.org/grpc/rpc_util.go | 330 +- .../vendor/google.golang.org/grpc/server.go | 99 +- .../grpc/shared_buffer_pool.go | 154 - .../google.golang.org/grpc/stats/stats.go | 6 - .../vendor/google.golang.org/grpc/stream.go | 213 +- .../grpc/stream_interfaces.go | 86 + .../vendor/google.golang.org/grpc/version.go | 2 +- .../protobuf/encoding/protojson/decode.go | 5 - .../encoding/protojson/well_known_types.go | 6 +- .../protobuf/encoding/prototext/decode.go | 5 - .../editiondefaults/editions_defaults.binpb | Bin 93 -> 138 bytes .../internal/editionssupport/editions.go | 13 - .../protobuf/internal/encoding/tag/tag.go | 8 +- .../protobuf/internal/errors/is_go112.go | 40 - .../protobuf/internal/errors/is_go113.go | 13 - .../protobuf/internal/filedesc/desc.go | 27 +- .../protobuf/internal/filedesc/desc_lazy.go | 9 - .../protobuf/internal/filedesc/editions.go | 8 + .../protobuf/internal/filetype/build.go | 2 +- .../protobuf/internal/flags/flags.go | 2 +- .../internal/genid/go_features_gen.go | 34 + .../protobuf/internal/genid/goname.go | 5 - .../protobuf/internal/genid/name.go | 12 + .../internal/impl/api_export_opaque.go | 128 + .../protobuf/internal/impl/bitmap.go | 34 + .../protobuf/internal/impl/bitmap_race.go | 126 + .../protobuf/internal/impl/checkinit.go | 33 + .../protobuf/internal/impl/codec_field.go | 75 - .../internal/impl/codec_field_opaque.go | 264 + .../protobuf/internal/impl/codec_map.go | 14 +- .../protobuf/internal/impl/codec_map_go111.go | 38 - .../protobuf/internal/impl/codec_map_go112.go | 12 - .../protobuf/internal/impl/codec_message.go | 20 +- .../internal/impl/codec_message_opaque.go | 153 + .../protobuf/internal/impl/convert_map.go | 2 +- .../protobuf/internal/impl/decode.go | 56 +- .../protobuf/internal/impl/encode.go | 78 + .../protobuf/internal/impl/lazy.go | 433 + .../protobuf/internal/impl/legacy_message.go | 5 +- .../protobuf/internal/impl/merge.go | 27 + .../protobuf/internal/impl/message.go | 31 +- .../protobuf/internal/impl/message_opaque.go | 627 + .../internal/impl/message_opaque_gen.go | 132 + .../protobuf/internal/impl/message_reflect.go | 10 +- .../internal/impl/message_reflect_field.go | 160 +- .../impl/message_reflect_field_gen.go | 273 + .../protobuf/internal/impl/pointer_unsafe.go | 12 +- .../internal/impl/pointer_unsafe_opaque.go | 42 + .../protobuf/internal/impl/presence.go | 142 + .../protobuf/internal/impl/validate.go | 40 +- .../protobuf/internal/impl/weak.go | 74 - .../internal/protolazy/bufferreader.go | 364 + .../protobuf/internal/protolazy/lazy.go | 359 + .../internal/protolazy/pointer_unsafe.go | 17 + .../protobuf/internal/version/version.go | 4 +- .../protobuf/proto/decode.go | 21 +- .../protobuf/proto/encode.go | 3 +- .../google.golang.org/protobuf/proto/size.go | 8 + .../protobuf/proto/wrapperopaque.go | 80 + .../protobuf/reflect/protodesc/desc.go | 286 - .../protobuf/reflect/protodesc/desc_init.go | 289 - .../reflect/protodesc/desc_resolve.go | 291 - .../reflect/protodesc/desc_validate.go | 371 - .../protobuf/reflect/protodesc/editions.go | 145 - .../protobuf/reflect/protodesc/proto.go | 274 - .../protobuf/reflect/protoreflect/type.go | 12 +- .../protobuf/reflect/protoreflect/value.go | 2 +- .../protobuf/runtime/protoiface/methods.go | 16 + .../protobuf/runtime/protoimpl/impl.go | 4 + .../types/descriptorpb/descriptor.pb.go | 1785 ++- .../types/gofeaturespb/go_features.pb.go | 165 - .../protobuf/types/known/anypb/any.pb.go | 21 +- .../types/known/durationpb/duration.pb.go | 21 +- .../types/known/timestamppb/timestamp.pb.go | 21 +- .../vendor/k8s.io/api/admission/v1/doc.go | 2 +- .../k8s.io/api/admission/v1beta1/doc.go | 2 +- .../api/admissionregistration/v1/doc.go | 2 +- .../api/admissionregistration/v1alpha1/doc.go | 2 +- .../v1alpha1/generated.proto | 13 +- .../admissionregistration/v1alpha1/types.go | 23 +- .../v1alpha1/types_swagger_doc_generated.go | 8 +- .../api/admissionregistration/v1beta1/doc.go | 2 +- .../vendor/k8s.io/api/apidiscovery/v2/doc.go | 2 +- .../k8s.io/api/apidiscovery/v2beta1/doc.go | 2 +- .../api/apiserverinternal/v1alpha1/doc.go | 2 +- .../vendor/k8s.io/api/apps/v1/doc.go | 2 +- .../vendor/k8s.io/api/apps/v1/generated.pb.go | 336 +- .../vendor/k8s.io/api/apps/v1/generated.proto | 41 +- .../vendor/k8s.io/api/apps/v1/types.go | 41 +- .../apps/v1/types_swagger_doc_generated.go | 24 +- .../api/apps/v1/zz_generated.deepcopy.go | 10 + .../vendor/k8s.io/api/apps/v1beta1/doc.go | 2 +- .../k8s.io/api/apps/v1beta1/generated.pb.go | 286 +- .../k8s.io/api/apps/v1beta1/generated.proto | 22 +- .../vendor/k8s.io/api/apps/v1beta1/types.go | 22 +- .../v1beta1/types_swagger_doc_generated.go | 15 +- .../api/apps/v1beta1/zz_generated.deepcopy.go | 5 + .../vendor/k8s.io/api/apps/v1beta2/doc.go | 2 +- .../k8s.io/api/apps/v1beta2/generated.pb.go | 352 +- .../k8s.io/api/apps/v1beta2/generated.proto | 41 +- .../vendor/k8s.io/api/apps/v1beta2/types.go | 41 +- .../v1beta2/types_swagger_doc_generated.go | 24 +- .../api/apps/v1beta2/zz_generated.deepcopy.go | 10 + .../k8s.io/api/authentication/v1/doc.go | 2 +- .../k8s.io/api/authentication/v1alpha1/doc.go | 2 +- .../k8s.io/api/authentication/v1beta1/doc.go | 2 +- .../vendor/k8s.io/api/authorization/v1/doc.go | 2 +- .../k8s.io/api/authorization/v1beta1/doc.go | 2 +- .../vendor/k8s.io/api/autoscaling/v1/doc.go | 2 +- .../vendor/k8s.io/api/autoscaling/v2/doc.go | 2 +- .../k8s.io/api/autoscaling/v2/generated.pb.go | 272 +- .../k8s.io/api/autoscaling/v2/generated.proto | 30 +- .../vendor/k8s.io/api/autoscaling/v2/types.go | 30 +- .../v2/types_swagger_doc_generated.go | 5 +- .../autoscaling/v2/zz_generated.deepcopy.go | 5 + .../k8s.io/api/autoscaling/v2beta1/doc.go | 2 +- .../k8s.io/api/autoscaling/v2beta2/doc.go | 2 +- .../vendor/k8s.io/api/batch/v1/doc.go | 2 +- .../k8s.io/api/batch/v1/generated.proto | 10 - .../vendor/k8s.io/api/batch/v1/types.go | 15 - .../batch/v1/types_swagger_doc_generated.go | 10 +- .../vendor/k8s.io/api/batch/v1beta1/doc.go | 2 +- .../vendor/k8s.io/api/certificates/v1/doc.go | 2 +- .../k8s.io/api/certificates/v1alpha1/doc.go | 2 +- .../k8s.io/api/certificates/v1beta1/doc.go | 2 +- .../api/certificates/v1beta1/generated.pb.go | 761 +- .../api/certificates/v1beta1/generated.proto | 73 + .../api/certificates/v1beta1/register.go | 2 + .../k8s.io/api/certificates/v1beta1/types.go | 85 + .../v1beta1/types_swagger_doc_generated.go | 30 + .../v1beta1/zz_generated.deepcopy.go | 76 + .../zz_generated.prerelease-lifecycle.go | 36 + .../vendor/k8s.io/api/coordination/v1/doc.go | 2 +- .../k8s.io/api/coordination/v1alpha2/doc.go | 2 +- .../api/coordination/v1alpha2/generated.proto | 2 - .../k8s.io/api/coordination/v1alpha2/types.go | 2 - .../v1alpha2/types_swagger_doc_generated.go | 2 +- .../k8s.io/api/coordination/v1beta1/doc.go | 2 +- .../api/coordination/v1beta1/generated.pb.go | 915 +- .../api/coordination/v1beta1/generated.proto | 69 + .../api/coordination/v1beta1/register.go | 2 + .../k8s.io/api/coordination/v1beta1/types.go | 73 + .../v1beta1/types_swagger_doc_generated.go | 34 + .../v1beta1/zz_generated.deepcopy.go | 84 + .../zz_generated.prerelease-lifecycle.go | 36 + .../vendor/k8s.io/api/core/v1/doc.go | 2 +- .../vendor/k8s.io/api/core/v1/generated.pb.go | 2767 ++-- .../vendor/k8s.io/api/core/v1/generated.proto | 77 +- .../vendor/k8s.io/api/core/v1/lifecycle.go | 24 + .../vendor/k8s.io/api/core/v1/types.go | 201 +- .../core/v1/types_swagger_doc_generated.go | 50 +- .../api/core/v1/zz_generated.deepcopy.go | 38 +- .../vendor/k8s.io/api/discovery/v1/doc.go | 2 +- .../k8s.io/api/discovery/v1/generated.pb.go | 336 +- .../k8s.io/api/discovery/v1/generated.proto | 78 +- .../vendor/k8s.io/api/discovery/v1/types.go | 78 +- .../v1/types_swagger_doc_generated.go | 28 +- .../api/discovery/v1/zz_generated.deepcopy.go | 21 + .../k8s.io/api/discovery/v1beta1/doc.go | 2 +- .../api/discovery/v1beta1/generated.pb.go | 329 +- .../api/discovery/v1beta1/generated.proto | 13 + .../k8s.io/api/discovery/v1beta1/types.go | 13 + .../v1beta1/types_swagger_doc_generated.go | 10 + .../v1beta1/zz_generated.deepcopy.go | 21 + .../vendor/k8s.io/api/events/v1/doc.go | 2 +- .../vendor/k8s.io/api/events/v1beta1/doc.go | 2 +- .../k8s.io/api/extensions/v1beta1/doc.go | 2 +- .../api/extensions/v1beta1/generated.pb.go | 418 +- .../api/extensions/v1beta1/generated.proto | 40 +- .../k8s.io/api/extensions/v1beta1/types.go | 40 +- .../v1beta1/types_swagger_doc_generated.go | 24 +- .../v1beta1/zz_generated.deepcopy.go | 10 + .../vendor/k8s.io/api/flowcontrol/v1/doc.go | 2 +- .../k8s.io/api/flowcontrol/v1beta1/doc.go | 2 +- .../k8s.io/api/flowcontrol/v1beta2/doc.go | 2 +- .../k8s.io/api/flowcontrol/v1beta3/doc.go | 2 +- .../k8s.io/api/imagepolicy/v1alpha1/doc.go | 2 +- .../vendor/k8s.io/api/networking/v1/doc.go | 2 +- .../k8s.io/api/networking/v1/generated.pb.go | 3729 ++++-- .../k8s.io/api/networking/v1/generated.proto | 109 + .../k8s.io/api/networking/v1/register.go | 4 + .../vendor/k8s.io/api/networking/v1/types.go | 130 + .../v1/types_swagger_doc_generated.go | 80 + .../api/networking/v1/well_known_labels.go | 33 + .../networking/v1/zz_generated.deepcopy.go | 202 + .../v1/zz_generated.prerelease-lifecycle.go | 24 + .../k8s.io/api/networking/v1alpha1/doc.go | 2 +- .../k8s.io/api/networking/v1beta1/doc.go | 2 +- .../vendor/k8s.io/api/node/v1/doc.go | 2 +- .../vendor/k8s.io/api/node/v1alpha1/doc.go | 2 +- .../vendor/k8s.io/api/node/v1beta1/doc.go | 2 +- .../vendor/k8s.io/api/policy/v1/doc.go | 2 +- .../k8s.io/api/policy/v1/generated.proto | 3 - .../vendor/k8s.io/api/policy/v1/types.go | 3 - .../policy/v1/types_swagger_doc_generated.go | 2 +- .../vendor/k8s.io/api/policy/v1beta1/doc.go | 2 +- .../k8s.io/api/policy/v1beta1/generated.proto | 3 - .../vendor/k8s.io/api/policy/v1beta1/types.go | 3 - .../v1beta1/types_swagger_doc_generated.go | 2 +- .../vendor/k8s.io/api/rbac/v1/doc.go | 2 +- .../vendor/k8s.io/api/rbac/v1alpha1/doc.go | 2 +- .../vendor/k8s.io/api/rbac/v1beta1/doc.go | 2 +- .../k8s.io/api/resource/v1alpha3/doc.go | 2 +- .../api/resource/v1alpha3/generated.pb.go | 6403 ++++++--- .../api/resource/v1alpha3/generated.proto | 514 +- .../k8s.io/api/resource/v1alpha3/register.go | 2 + .../k8s.io/api/resource/v1alpha3/types.go | 609 +- .../v1alpha3/types_swagger_doc_generated.go | 165 +- .../v1alpha3/zz_generated.deepcopy.go | 327 +- .../zz_generated.prerelease-lifecycle.go | 36 + .../api/resource/v1beta1/devicetaint.go | 35 + .../vendor/k8s.io/api/resource/v1beta1/doc.go | 2 +- .../api/resource/v1beta1/generated.pb.go | 3890 ++++-- .../api/resource/v1beta1/generated.proto | 428 +- .../k8s.io/api/resource/v1beta1/types.go | 506 +- .../v1beta1/types_swagger_doc_generated.go | 124 +- .../resource/v1beta1/zz_generated.deepcopy.go | 202 +- .../api/resource/v1beta2/devicetaint.go | 35 + .../vendor/k8s.io/api/resource/v1beta2/doc.go | 24 + .../api/resource/v1beta2/generated.pb.go | 11047 ++++++++++++++++ .../api/resource/v1beta2/generated.proto | 1278 ++ .../k8s.io/api/resource/v1beta2/register.go | 60 + .../k8s.io/api/resource/v1beta2/types.go | 1552 +++ .../v1beta2/types_swagger_doc_generated.go | 464 + .../resource/v1beta2/zz_generated.deepcopy.go | 1092 ++ .../zz_generated.prerelease-lifecycle.go | 166 + .../vendor/k8s.io/api/scheduling/v1/doc.go | 2 +- .../k8s.io/api/scheduling/v1alpha1/doc.go | 2 +- .../k8s.io/api/scheduling/v1beta1/doc.go | 2 +- .../vendor/k8s.io/api/storage/v1/doc.go | 2 +- .../k8s.io/api/storage/v1/generated.pb.go | 271 +- .../k8s.io/api/storage/v1/generated.proto | 22 + .../vendor/k8s.io/api/storage/v1/types.go | 22 + .../storage/v1/types_swagger_doc_generated.go | 26 +- .../api/storage/v1/zz_generated.deepcopy.go | 10 + .../vendor/k8s.io/api/storage/v1alpha1/doc.go | 2 +- .../api/storage/v1alpha1/generated.pb.go | 160 +- .../api/storage/v1alpha1/generated.proto | 8 + .../k8s.io/api/storage/v1alpha1/types.go | 8 + .../v1alpha1/types_swagger_doc_generated.go | 7 +- .../storage/v1alpha1/zz_generated.deepcopy.go | 5 + .../vendor/k8s.io/api/storage/v1beta1/doc.go | 2 +- .../api/storage/v1beta1/generated.pb.go | 280 +- .../api/storage/v1beta1/generated.proto | 22 + .../k8s.io/api/storage/v1beta1/types.go | 22 + .../v1beta1/types_swagger_doc_generated.go | 26 +- .../storage/v1beta1/zz_generated.deepcopy.go | 10 + .../api/storagemigration/v1alpha1/doc.go | 2 +- .../pkg/apis/apiextensions/doc.go | 2 +- .../pkg/apis/apiextensions/v1/doc.go | 2 +- .../pkg/features/OWNERS | 4 + .../pkg/features/kube_features.go | 66 + .../k8s.io/apimachinery/pkg/api/errors/doc.go | 2 +- .../k8s.io/apimachinery/pkg/api/meta/doc.go | 2 +- .../k8s.io/apimachinery/pkg/api/meta/help.go | 3 + .../pkg/api/operation/operation.go | 56 + .../apimachinery/pkg/api/validation/doc.go | 2 +- .../pkg/api/validation/generic.go | 2 +- .../pkg/apis/meta/internalversion/doc.go | 2 +- .../apis/meta/internalversion/scheme/doc.go | 2 +- .../pkg/apis/meta/internalversion/types.go | 2 - .../apimachinery/pkg/apis/meta/v1/doc.go | 2 +- .../pkg/apis/meta/v1/micro_time_fuzz.go | 13 +- .../pkg/apis/meta/v1/time_fuzz.go | 13 +- .../pkg/apis/meta/v1/unstructured/helpers.go | 31 +- .../apis/meta/v1/unstructured/unstructured.go | 4 +- .../pkg/apis/meta/v1/validation/validation.go | 2 +- .../apimachinery/pkg/apis/meta/v1beta1/doc.go | 2 +- .../k8s.io/apimachinery/pkg/conversion/doc.go | 2 +- .../pkg/conversion/queryparams/doc.go | 2 +- .../k8s.io/apimachinery/pkg/fields/doc.go | 2 +- .../k8s.io/apimachinery/pkg/labels/doc.go | 2 +- .../k8s.io/apimachinery/pkg/runtime/doc.go | 2 +- .../apimachinery/pkg/runtime/interfaces.go | 1 + .../k8s.io/apimachinery/pkg/runtime/scheme.go | 39 + .../serializer/cbor/internal/modes/custom.go | 4 +- .../pkg/runtime/serializer/codec_factory.go | 23 +- .../runtime/serializer/json/collections.go | 230 + .../pkg/runtime/serializer/json/json.go | 16 +- .../serializer/protobuf/collections.go | 174 + .../pkg/runtime/serializer/protobuf/doc.go | 2 +- .../runtime/serializer/protobuf/protobuf.go | 87 +- .../apimachinery/pkg/runtime/types_proto.go | 127 +- .../k8s.io/apimachinery/pkg/types/doc.go | 2 +- .../k8s.io/apimachinery/pkg/util/diff/diff.go | 2 +- .../apimachinery/pkg/util/errors/doc.go | 2 +- .../apimachinery/pkg/util/framer/framer.go | 6 +- .../apimachinery/pkg/util/httpstream/doc.go | 2 +- .../pkg/util/httpstream/wsstream/doc.go | 2 +- .../pkg/util/intstr/instr_fuzz.go | 14 +- .../k8s.io/apimachinery/pkg/util/proxy/doc.go | 2 +- .../apimachinery/pkg/util/runtime/runtime.go | 46 +- .../k8s.io/apimachinery/pkg/util/sets/doc.go | 2 +- .../util/validation/field/error_matcher.go | 212 + .../pkg/util/validation/field/errors.go | 132 +- .../apimachinery/pkg/util/validation/ip.go | 278 + .../pkg/util/validation/validation.go | 40 - .../apimachinery/pkg/util/version/doc.go | 2 +- .../apimachinery/pkg/util/version/version.go | 18 +- .../apimachinery/pkg/util/wait/backoff.go | 50 +- .../k8s.io/apimachinery/pkg/util/wait/doc.go | 2 +- .../k8s.io/apimachinery/pkg/util/wait/loop.go | 4 +- .../k8s.io/apimachinery/pkg/util/wait/wait.go | 9 +- .../apimachinery/pkg/util/yaml/decoder.go | 170 +- .../pkg/util/yaml/stream_reader.go | 130 + .../k8s.io/apimachinery/pkg/version/doc.go | 4 +- .../k8s.io/apimachinery/pkg/version/types.go | 28 +- .../k8s.io/apimachinery/pkg/watch/doc.go | 2 +- .../apimachinery/pkg/watch/streamwatcher.go | 15 +- .../k8s.io/apimachinery/pkg/watch/watch.go | 35 +- .../gofuzz => k8s.io/apiserver}/LICENSE | 0 .../k8s.io/apiserver/pkg/features/OWNERS | 4 + .../apiserver/pkg/features/kube_features.go | 421 + .../pkg/util/feature/feature_gate.go | 33 + .../client-go/applyconfigurations/OWNERS | 1 + .../apps/v1/deploymentstatus.go | 9 + .../apps/v1/replicasetstatus.go | 9 + .../apps/v1beta1/deploymentstatus.go | 9 + .../apps/v1beta2/deploymentstatus.go | 9 + .../apps/v1beta2/replicasetstatus.go | 9 + .../autoscaling/v2/hpascalingrules.go | 10 + .../v1beta1/clustertrustbundle.go | 253 + .../v1beta1/clustertrustbundlespec.go | 48 + .../coordination/v1beta1/leasecandidate.go | 255 + .../v1beta1/leasecandidatespec.go | 89 + .../core/v1/containerstatus.go | 9 + .../applyconfigurations/core/v1/lifecycle.go | 17 +- .../core/v1/nodeswapstatus.go | 39 + .../core/v1/nodesysteminfo.go | 29 +- .../core/v1/podcondition.go | 9 + .../applyconfigurations/core/v1/podstatus.go | 9 + .../discovery/v1/endpointhints.go | 14 + .../discovery/v1/fornode.go | 39 + .../discovery/v1beta1/endpointhints.go | 14 + .../discovery/v1beta1/fornode.go | 39 + .../client-go/applyconfigurations/doc.go | 2 +- .../extensions/v1beta1/deploymentstatus.go | 9 + .../extensions/v1beta1/replicasetstatus.go | 9 + .../applyconfigurations/internal/internal.go | 1344 +- .../networking/v1/ipaddress.go | 253 + .../networking/v1/ipaddressspec.go | 39 + .../networking/v1/parentreference.go | 66 + .../networking/v1/servicecidr.go | 262 + .../networking/v1/servicecidrspec.go | 41 + .../networking/v1/servicecidrstatus.go | 48 + .../resource/v1alpha3/basicdevice.go | 60 +- .../resource/v1alpha3/counter.go | 43 + .../resource/v1alpha3/counterset.go | 54 + .../v1alpha3/devicecounterconsumption.go | 54 + .../resource/v1alpha3/devicerequest.go | 28 + .../v1alpha3/devicerequestallocationresult.go | 24 +- .../resource/v1alpha3/devicesubrequest.go | 98 + .../resource/v1alpha3/devicetaint.go | 71 + .../resource/v1alpha3/devicetaintrule.go | 253 + .../resource/v1alpha3/devicetaintrulespec.go | 48 + .../resource/v1alpha3/devicetaintselector.go | 80 + .../resource/v1alpha3/devicetoleration.go | 79 + .../resource/v1alpha3/resourceslicespec.go | 35 +- .../resource/v1beta1/basicdevice.go | 60 +- .../resource/v1beta1/counter.go | 43 + .../resource/v1beta1/counterset.go | 54 + .../v1beta1/devicecounterconsumption.go | 54 + .../resource/v1beta1/devicerequest.go | 28 + .../v1beta1/devicerequestallocationresult.go | 24 +- .../resource/v1beta1/devicesubrequest.go | 98 + .../resource/v1beta1/devicetaint.go | 71 + .../resource/v1beta1/devicetoleration.go | 79 + .../resource/v1beta1/resourceslicespec.go | 35 +- .../resource/v1beta2/allocateddevicestatus.go | 94 + .../resource/v1beta2/allocationresult.go | 52 + .../resource/v1beta2/celdeviceselector.go | 39 + .../resource/v1beta2/counter.go | 43 + .../resource/v1beta2/counterset.go | 54 + .../resource/v1beta2/device.go | 129 + .../v1beta2/deviceallocationconfiguration.go | 63 + .../v1beta2/deviceallocationresult.go | 58 + .../resource/v1beta2/deviceattribute.go | 66 + .../resource/v1beta2/devicecapacity.go | 43 + .../resource/v1beta2/deviceclaim.go | 72 + .../v1beta2/deviceclaimconfiguration.go | 50 + .../resource/v1beta2/deviceclass.go | 253 + .../v1beta2/deviceclassconfiguration.go | 39 + .../resource/v1beta2/deviceclassspec.go | 58 + .../resource/v1beta2/deviceconfiguration.go | 39 + .../resource/v1beta2/deviceconstraint.go | 54 + .../v1beta2/devicecounterconsumption.go | 54 + .../resource/v1beta2/devicerequest.go | 62 + .../v1beta2/devicerequestallocationresult.go | 89 + .../resource/v1beta2/deviceselector.go | 39 + .../resource/v1beta2/devicesubrequest.go | 98 + .../resource/v1beta2/devicetaint.go | 71 + .../resource/v1beta2/devicetoleration.go | 79 + .../resource/v1beta2/exactdevicerequest.go | 98 + .../resource/v1beta2/networkdevicedata.go | 59 + .../v1beta2/opaquedeviceconfiguration.go | 52 + .../resource/v1beta2/resourceclaim.go | 264 + .../v1beta2/resourceclaimconsumerreference.go | 70 + .../resource/v1beta2/resourceclaimspec.go | 39 + .../resource/v1beta2/resourceclaimstatus.go | 67 + .../resource/v1beta2/resourceclaimtemplate.go | 255 + .../v1beta2/resourceclaimtemplatespec.go | 194 + .../resource/v1beta2/resourcepool.go | 57 + .../resource/v1beta2/resourceslice.go | 253 + .../resource/v1beta2/resourceslicespec.go | 116 + .../storage/v1/csidriverspec.go | 25 +- .../storage/v1/volumeerror.go | 13 +- .../storage/v1alpha1/volumeerror.go | 13 +- .../storage/v1beta1/csidriverspec.go | 25 +- .../storage/v1beta1/volumeerror.go | 13 +- .../client-go/applyconfigurations/utils.go | 132 + .../discovery/aggregated_discovery.go | 2 +- .../client-go/discovery/discovery_client.go | 3 +- .../vendor/k8s.io/client-go/discovery/doc.go | 2 +- .../client-go/features/known_features.go | 7 + .../vendor/k8s.io/client-go/gentype/fake.go | 1 + .../v1/mutatingwebhookconfiguration.go | 16 +- .../v1/validatingadmissionpolicy.go | 16 +- .../v1/validatingadmissionpolicybinding.go | 16 +- .../v1/validatingwebhookconfiguration.go | 16 +- .../v1alpha1/mutatingadmissionpolicy.go | 16 +- .../mutatingadmissionpolicybinding.go | 16 +- .../v1alpha1/validatingadmissionpolicy.go | 16 +- .../validatingadmissionpolicybinding.go | 16 +- .../v1beta1/mutatingwebhookconfiguration.go | 16 +- .../v1beta1/validatingadmissionpolicy.go | 16 +- .../validatingadmissionpolicybinding.go | 16 +- .../v1beta1/validatingwebhookconfiguration.go | 16 +- .../v1alpha1/storageversion.go | 16 +- .../informers/apps/v1/controllerrevision.go | 16 +- .../client-go/informers/apps/v1/daemonset.go | 16 +- .../client-go/informers/apps/v1/deployment.go | 16 +- .../client-go/informers/apps/v1/replicaset.go | 16 +- .../informers/apps/v1/statefulset.go | 16 +- .../apps/v1beta1/controllerrevision.go | 16 +- .../informers/apps/v1beta1/deployment.go | 16 +- .../informers/apps/v1beta1/statefulset.go | 16 +- .../apps/v1beta2/controllerrevision.go | 16 +- .../informers/apps/v1beta2/daemonset.go | 16 +- .../informers/apps/v1beta2/deployment.go | 16 +- .../informers/apps/v1beta2/replicaset.go | 16 +- .../informers/apps/v1beta2/statefulset.go | 16 +- .../autoscaling/v1/horizontalpodautoscaler.go | 16 +- .../autoscaling/v2/horizontalpodautoscaler.go | 16 +- .../v2beta1/horizontalpodautoscaler.go | 16 +- .../v2beta2/horizontalpodautoscaler.go | 16 +- .../client-go/informers/batch/v1/cronjob.go | 16 +- .../client-go/informers/batch/v1/job.go | 16 +- .../informers/batch/v1beta1/cronjob.go | 16 +- .../v1/certificatesigningrequest.go | 16 +- .../v1alpha1/clustertrustbundle.go | 16 +- .../v1beta1/certificatesigningrequest.go | 16 +- .../v1beta1/clustertrustbundle.go | 101 + .../certificates/v1beta1/interface.go | 7 + .../informers/coordination/v1/lease.go | 16 +- .../coordination/v1alpha2/leasecandidate.go | 16 +- .../coordination/v1beta1/interface.go | 7 + .../informers/coordination/v1beta1/lease.go | 16 +- .../coordination/v1beta1/leasecandidate.go | 102 + .../informers/core/v1/componentstatus.go | 16 +- .../client-go/informers/core/v1/configmap.go | 16 +- .../client-go/informers/core/v1/endpoints.go | 16 +- .../client-go/informers/core/v1/event.go | 16 +- .../client-go/informers/core/v1/limitrange.go | 16 +- .../client-go/informers/core/v1/namespace.go | 16 +- .../client-go/informers/core/v1/node.go | 16 +- .../informers/core/v1/persistentvolume.go | 16 +- .../core/v1/persistentvolumeclaim.go | 16 +- .../k8s.io/client-go/informers/core/v1/pod.go | 16 +- .../informers/core/v1/podtemplate.go | 16 +- .../core/v1/replicationcontroller.go | 16 +- .../informers/core/v1/resourcequota.go | 16 +- .../client-go/informers/core/v1/secret.go | 16 +- .../client-go/informers/core/v1/service.go | 16 +- .../informers/core/v1/serviceaccount.go | 16 +- .../informers/discovery/v1/endpointslice.go | 16 +- .../discovery/v1beta1/endpointslice.go | 16 +- .../vendor/k8s.io/client-go/informers/doc.go | 2 +- .../client-go/informers/events/v1/event.go | 16 +- .../informers/events/v1beta1/event.go | 16 +- .../informers/extensions/v1beta1/daemonset.go | 16 +- .../extensions/v1beta1/deployment.go | 16 +- .../informers/extensions/v1beta1/ingress.go | 16 +- .../extensions/v1beta1/networkpolicy.go | 16 +- .../extensions/v1beta1/replicaset.go | 16 +- .../informers/flowcontrol/v1/flowschema.go | 16 +- .../v1/prioritylevelconfiguration.go | 16 +- .../flowcontrol/v1beta1/flowschema.go | 16 +- .../v1beta1/prioritylevelconfiguration.go | 16 +- .../flowcontrol/v1beta2/flowschema.go | 16 +- .../v1beta2/prioritylevelconfiguration.go | 16 +- .../flowcontrol/v1beta3/flowschema.go | 16 +- .../v1beta3/prioritylevelconfiguration.go | 16 +- .../k8s.io/client-go/informers/generic.go | 21 + .../informers/networking/v1/ingress.go | 16 +- .../informers/networking/v1/ingressclass.go | 16 +- .../informers/networking/v1/interface.go | 14 + .../informers/networking/v1/ipaddress.go | 101 + .../informers/networking/v1/networkpolicy.go | 16 +- .../informers/networking/v1/servicecidr.go | 101 + .../networking/v1alpha1/ipaddress.go | 16 +- .../networking/v1alpha1/servicecidr.go | 16 +- .../informers/networking/v1beta1/ingress.go | 16 +- .../networking/v1beta1/ingressclass.go | 16 +- .../informers/networking/v1beta1/ipaddress.go | 16 +- .../networking/v1beta1/servicecidr.go | 16 +- .../informers/node/v1/runtimeclass.go | 16 +- .../informers/node/v1alpha1/runtimeclass.go | 16 +- .../informers/node/v1beta1/runtimeclass.go | 16 +- .../policy/v1/poddisruptionbudget.go | 16 +- .../policy/v1beta1/poddisruptionbudget.go | 16 +- .../informers/rbac/v1/clusterrole.go | 16 +- .../informers/rbac/v1/clusterrolebinding.go | 16 +- .../client-go/informers/rbac/v1/role.go | 16 +- .../informers/rbac/v1/rolebinding.go | 16 +- .../informers/rbac/v1alpha1/clusterrole.go | 16 +- .../rbac/v1alpha1/clusterrolebinding.go | 16 +- .../client-go/informers/rbac/v1alpha1/role.go | 16 +- .../informers/rbac/v1alpha1/rolebinding.go | 16 +- .../informers/rbac/v1beta1/clusterrole.go | 16 +- .../rbac/v1beta1/clusterrolebinding.go | 16 +- .../client-go/informers/rbac/v1beta1/role.go | 16 +- .../informers/rbac/v1beta1/rolebinding.go | 16 +- .../client-go/informers/resource/interface.go | 8 + .../resource/v1alpha3/deviceclass.go | 16 +- .../resource/v1alpha3/devicetaintrule.go | 101 + .../informers/resource/v1alpha3/interface.go | 7 + .../resource/v1alpha3/resourceclaim.go | 16 +- .../v1alpha3/resourceclaimtemplate.go | 16 +- .../resource/v1alpha3/resourceslice.go | 16 +- .../informers/resource/v1beta1/deviceclass.go | 16 +- .../resource/v1beta1/resourceclaim.go | 16 +- .../resource/v1beta1/resourceclaimtemplate.go | 16 +- .../resource/v1beta1/resourceslice.go | 16 +- .../informers/resource/v1beta2/deviceclass.go | 101 + .../informers/resource/v1beta2/interface.go | 66 + .../resource/v1beta2/resourceclaim.go | 102 + .../resource/v1beta2/resourceclaimtemplate.go | 102 + .../resource/v1beta2/resourceslice.go | 101 + .../informers/scheduling/v1/priorityclass.go | 16 +- .../scheduling/v1alpha1/priorityclass.go | 16 +- .../scheduling/v1beta1/priorityclass.go | 16 +- .../informers/storage/v1/csidriver.go | 16 +- .../client-go/informers/storage/v1/csinode.go | 16 +- .../storage/v1/csistoragecapacity.go | 16 +- .../informers/storage/v1/storageclass.go | 16 +- .../informers/storage/v1/volumeattachment.go | 16 +- .../storage/v1alpha1/csistoragecapacity.go | 16 +- .../storage/v1alpha1/volumeattachment.go | 16 +- .../storage/v1alpha1/volumeattributesclass.go | 16 +- .../informers/storage/v1beta1/csidriver.go | 16 +- .../informers/storage/v1beta1/csinode.go | 16 +- .../storage/v1beta1/csistoragecapacity.go | 16 +- .../informers/storage/v1beta1/storageclass.go | 16 +- .../storage/v1beta1/volumeattachment.go | 16 +- .../storage/v1beta1/volumeattributesclass.go | 16 +- .../v1alpha1/storageversionmigration.go | 16 +- .../k8s.io/client-go/kubernetes/clientset.go | 13 + .../vendor/k8s.io/client-go/kubernetes/doc.go | 2 +- .../kubernetes/fake/clientset_generated.go | 20 +- .../client-go/kubernetes/fake/register.go | 2 + .../k8s.io/client-go/kubernetes/import.go | 2 +- .../client-go/kubernetes/scheme/register.go | 2 + .../v1/admissionregistration_client.go | 12 +- .../v1alpha1/admissionregistration_client.go | 12 +- .../v1beta1/admissionregistration_client.go | 12 +- .../v1alpha1/apiserverinternal_client.go | 12 +- .../kubernetes/typed/apps/v1/apps_client.go | 12 +- .../typed/apps/v1beta1/apps_client.go | 12 +- .../typed/apps/v1beta2/apps_client.go | 12 +- .../v1/authentication_client.go | 12 +- .../v1alpha1/authentication_client.go | 12 +- .../v1beta1/authentication_client.go | 12 +- .../authorization/v1/authorization_client.go | 12 +- .../v1beta1/authorization_client.go | 12 +- .../autoscaling/v1/autoscaling_client.go | 12 +- .../autoscaling/v2/autoscaling_client.go | 12 +- .../autoscaling/v2beta1/autoscaling_client.go | 12 +- .../autoscaling/v2beta2/autoscaling_client.go | 12 +- .../kubernetes/typed/batch/v1/batch_client.go | 12 +- .../typed/batch/v1beta1/batch_client.go | 12 +- .../certificates/v1/certificates_client.go | 12 +- .../v1alpha1/certificates_client.go | 12 +- .../v1beta1/certificates_client.go | 17 +- .../v1beta1/clustertrustbundle.go | 73 + .../v1beta1/fake/fake_certificates_client.go | 4 + .../v1beta1/fake/fake_clustertrustbundle.go | 53 + .../v1beta1/generated_expansion.go | 2 + .../coordination/v1/coordination_client.go | 12 +- .../v1alpha2/coordination_client.go | 12 +- .../v1beta1/coordination_client.go | 17 +- .../v1beta1/fake/fake_coordination_client.go | 4 + .../v1beta1/fake/fake_leasecandidate.go | 53 + .../v1beta1/generated_expansion.go | 2 + .../coordination/v1beta1/leasecandidate.go | 71 + .../kubernetes/typed/core/v1/core_client.go | 12 +- .../typed/core/v1/event_expansion.go | 65 +- .../core/v1/fake/fake_event_expansion.go | 29 + .../typed/discovery/v1/discovery_client.go | 12 +- .../discovery/v1beta1/discovery_client.go | 12 +- .../typed/events/v1/events_client.go | 12 +- .../typed/events/v1beta1/event_expansion.go | 6 +- .../typed/events/v1beta1/events_client.go | 12 +- .../extensions/v1beta1/extensions_client.go | 12 +- .../flowcontrol/v1/flowcontrol_client.go | 12 +- .../flowcontrol/v1beta1/flowcontrol_client.go | 12 +- .../flowcontrol/v1beta2/flowcontrol_client.go | 12 +- .../flowcontrol/v1beta3/flowcontrol_client.go | 12 +- .../networking/v1/fake/fake_ipaddress.go | 49 + .../v1/fake/fake_networking_client.go | 8 + .../networking/v1/fake/fake_servicecidr.go | 49 + .../networking/v1/generated_expansion.go | 4 + .../typed/networking/v1/ipaddress.go | 71 + .../typed/networking/v1/networking_client.go | 22 +- .../typed/networking/v1/servicecidr.go | 75 + .../networking/v1alpha1/networking_client.go | 12 +- .../networking/v1beta1/networking_client.go | 12 +- .../kubernetes/typed/node/v1/node_client.go | 12 +- .../typed/node/v1alpha1/node_client.go | 12 +- .../typed/node/v1beta1/node_client.go | 12 +- .../typed/policy/v1/policy_client.go | 12 +- .../typed/policy/v1beta1/policy_client.go | 12 +- .../kubernetes/typed/rbac/v1/rbac_client.go | 12 +- .../typed/rbac/v1alpha1/rbac_client.go | 12 +- .../typed/rbac/v1beta1/rbac_client.go | 12 +- .../resource/v1alpha3/devicetaintrule.go | 71 + .../v1alpha3/fake/fake_devicetaintrule.go | 53 + .../v1alpha3/fake/fake_resource_client.go | 4 + .../resource/v1alpha3/generated_expansion.go | 2 + .../resource/v1alpha3/resource_client.go | 17 +- .../typed/resource/v1beta1/resource_client.go | 12 +- .../typed/resource/v1beta2/deviceclass.go | 71 + .../kubernetes/typed/resource/v1beta2/doc.go | 20 + .../typed/resource/v1beta2/fake}/doc.go | 8 +- .../resource/v1beta2/fake/fake_deviceclass.go | 51 + .../v1beta2/fake/fake_resource_client.go | 52 + .../v1beta2/fake/fake_resourceclaim.go | 53 + .../fake/fake_resourceclaimtemplate.go | 53 + .../v1beta2/fake/fake_resourceslice.go | 53 + .../resource/v1beta2/generated_expansion.go | 27 + .../typed/resource/v1beta2/resource_client.go | 116 + .../typed/resource/v1beta2/resourceclaim.go | 75 + .../resource/v1beta2/resourceclaimtemplate.go | 71 + .../typed/resource/v1beta2/resourceslice.go | 71 + .../typed/scheduling/v1/scheduling_client.go | 12 +- .../scheduling/v1alpha1/scheduling_client.go | 12 +- .../scheduling/v1beta1/scheduling_client.go | 12 +- .../typed/storage/v1/storage_client.go | 12 +- .../typed/storage/v1alpha1/storage_client.go | 12 +- .../typed/storage/v1beta1/storage_client.go | 12 +- .../v1alpha1/storagemigration_client.go | 12 +- .../v1beta1/clustertrustbundle.go | 48 + .../v1beta1/expansion_generated.go | 4 + .../v1beta1/expansion_generated.go | 8 + .../coordination/v1beta1/leasecandidate.go | 70 + .../vendor/k8s.io/client-go/listers/doc.go | 2 +- .../networking/v1/expansion_generated.go | 8 + .../listers/networking/v1/ipaddress.go | 48 + .../listers/networking/v1/servicecidr.go | 48 + .../resource/v1alpha3/devicetaintrule.go | 48 + .../resource/v1alpha3/expansion_generated.go | 4 + .../listers/resource/v1beta2/deviceclass.go | 48 + .../resource/v1beta2/expansion_generated.go | 43 + .../listers/resource/v1beta2/resourceclaim.go | 70 + .../resource/v1beta2/resourceclaimtemplate.go | 70 + .../listers/resource/v1beta2/resourceslice.go | 48 + .../pkg/apis/clientauthentication/doc.go | 2 +- .../pkg/apis/clientauthentication/v1/doc.go | 2 +- .../apis/clientauthentication/v1beta1/doc.go | 2 +- .../k8s.io/client-go/pkg/version/doc.go | 2 +- .../k8s.io/client-go/rest/.mockery.yaml | 10 + .../vendor/k8s.io/client-go/rest/client.go | 6 +- .../vendor/k8s.io/client-go/rest/config.go | 85 +- .../vendor/k8s.io/client-go/rest/plugin.go | 7 +- .../vendor/k8s.io/client-go/rest/request.go | 138 +- .../k8s.io/client-go/rest/urlbackoff.go | 101 +- .../vendor/k8s.io/client-go/rest/warnings.go | 57 +- .../k8s.io/client-go/rest/with_retry.go | 12 +- .../client-go/tools/cache/controller.go | 84 +- .../client-go/tools/cache/delta_fifo.go | 125 +- .../k8s.io/client-go/tools/cache/doc.go | 2 +- .../k8s.io/client-go/tools/cache/fifo.go | 97 +- .../k8s.io/client-go/tools/cache/listers.go | 7 +- .../k8s.io/client-go/tools/cache/listwatch.go | 174 +- .../client-go/tools/cache/mutation_cache.go | 8 +- .../tools/cache/mutation_detector.go | 1 + .../k8s.io/client-go/tools/cache/reflector.go | 238 +- .../client-go/tools/cache/shared_informer.go | 194 +- .../client-go/tools/cache/the_real_fifo.go | 407 + .../client-go/tools/clientcmd/api/doc.go | 2 +- .../client-go/tools/clientcmd/api/v1/doc.go | 2 +- .../k8s.io/client-go/tools/clientcmd/doc.go | 2 +- .../tools/leaderelection/leasecandidate.go | 18 +- .../k8s.io/client-go/tools/record/doc.go | 2 +- .../k8s.io/client-go/tools/record/event.go | 2 +- .../client-go/tools/record/util/util.go | 17 + .../client-go/tools/remotecommand/doc.go | 2 +- .../tools/remotecommand/errorstream.go | 2 +- .../tools/remotecommand/websocket.go | 19 +- .../client-go/tools/watch/informerwatcher.go | 18 +- .../client-go/tools/watch/retrywatcher.go | 103 +- .../k8s.io/client-go/tools/watch/until.go | 6 +- .../k8s.io/client-go/transport/cache.go | 8 +- .../client-go/transport/cert_rotation.go | 17 +- .../client-go/transport/round_trippers.go | 192 +- .../client-go/transport/token_source.go | 5 +- .../k8s.io/client-go/transport/transport.go | 2 +- .../vendor/k8s.io/client-go/util/cert/cert.go | 48 +- .../util/certificate/certificate_manager.go | 176 +- .../util/certificate/certificate_store.go | 23 +- .../client-go/util/certificate/csr/csr.go | 45 +- .../data_consistency_detector.go | 2 +- .../client-go/util/flowcontrol/backoff.go | 5 +- .../util/workqueue/delaying_queue.go | 19 +- .../k8s.io/client-go/util/workqueue/doc.go | 2 +- .../client-go/util/workqueue/parallelizer.go | 2 +- .../k8s.io/component-base/featuregate/OWNERS | 16 + .../featuregate/feature_gate.go | 769 ++ .../k8s.io/component-base/metrics/OWNERS | 11 + .../k8s.io/component-base/metrics/buckets.go | 53 + .../component-base/metrics/collector.go | 190 + .../k8s.io/component-base/metrics/counter.go | 306 + .../k8s.io/component-base/metrics/desc.go | 225 + .../k8s.io/component-base/metrics/gauge.go | 298 + .../component-base/metrics/histogram.go | 299 + .../k8s.io/component-base/metrics/http.go | 87 + .../k8s.io/component-base/metrics/labels.go | 22 + .../metrics/legacyregistry/registry.go | 92 + .../k8s.io/component-base/metrics/metric.go | 240 + .../k8s.io/component-base/metrics/options.go | 136 + .../k8s.io/component-base/metrics/opts.go | 390 + .../metrics/processstarttime.go | 51 + .../metrics/processstarttime_others.go | 39 + .../metrics/processstarttime_windows.go | 34 + .../metrics/prometheus/feature/metrics.go | 53 + .../prometheusextension/timing_histogram.go | 189 + .../timing_histogram_vec.go | 111 + .../prometheusextension/weighted_histogram.go | 203 + .../weighted_histogram_vec.go | 106 + .../k8s.io/component-base/metrics/registry.go | 394 + .../k8s.io/component-base/metrics/summary.go | 247 + .../metrics/timing_histogram.go | 291 + .../k8s.io/component-base/metrics/value.go | 70 + .../k8s.io/component-base/metrics/version.go | 37 + .../component-base/metrics/version_parser.go | 50 + .../k8s.io/component-base/metrics/wrappers.go | 167 + .../k8s.io/component-base/version/base.go | 2 +- .../k8s.io/component-base/version/version.go | 159 +- .../component-base/zpages/features/doc.go | 22 + .../zpages/features/kube_features.go | 52 + .../vendor/k8s.io/controller-manager/LICENSE | 201 + .../controller-manager/pkg/features/OWNERS | 4 + .../pkg/features/kube_features.go | 51 + .../kube-openapi/pkg/handler3/handler.go | 2 +- .../k8s.io/kube-openapi/pkg/spec3/fuzz.go | 146 +- .../k8s.io/kubernetes/pkg/api/v1/pod/util.go | 30 + .../k8s.io/kubernetes/pkg/apis/core/doc.go | 2 +- .../k8s.io/kubernetes/pkg/apis/core/types.go | 184 +- .../pkg/apis/core/zz_generated.deepcopy.go | 43 +- .../k8s.io/kubernetes/pkg/features/OWNERS | 4 + .../kubernetes/pkg/features/client_adapter.go | 76 + .../kubernetes/pkg/features/kube_features.go | 1894 +++ .../vendor/k8s.io/kubernetes/pkg/probe/doc.go | 2 +- .../kubernetes/pkg/util/iptables/doc.go | 2 +- .../kubernetes/pkg/util/iptables/iptables.go | 50 +- .../k8s.io/utils/clock/testing/fake_clock.go | 361 - .../clock/testing/simple_interval_clock.go | 44 - go-controller/vendor/modules.txt | 135 +- .../controller-runtime/.golangci.yml | 289 +- .../sigs.k8s.io/controller-runtime/Makefile | 6 +- .../controller-runtime/OWNERS_ALIASES | 2 + .../sigs.k8s.io/controller-runtime/README.md | 4 +- .../sigs.k8s.io/controller-runtime/alias.go | 6 + .../sigs.k8s.io/controller-runtime/doc.go | 2 +- .../pkg/builder/controller.go | 8 +- .../controller-runtime/pkg/builder/webhook.go | 61 +- .../controller-runtime/pkg/cache/cache.go | 8 +- .../pkg/cache/internal/cache_reader.go | 8 +- .../pkg/cache/internal/informers.go | 58 +- .../pkg/cache/multi_namespace_cache.go | 46 +- .../pkg/client/apiutil/restmapper.go | 20 +- .../controller-runtime/pkg/client/client.go | 9 +- .../pkg/client/config/config.go | 16 +- .../pkg/client/fake/client.go | 33 +- .../pkg/config/controller.go | 13 +- .../pkg/controller/controller.go | 86 +- .../controllerutil/controllerutil.go | 61 +- .../controller-runtime/pkg/controller/name.go | 2 +- .../pkg/controller/priorityqueue/metrics.go | 54 +- .../controller/priorityqueue/priorityqueue.go | 12 +- .../controller-runtime/pkg/event/event.go | 3 + .../controller-runtime/pkg/handler/enqueue.go | 19 +- .../pkg/handler/enqueue_mapped.go | 44 +- .../pkg/handler/enqueue_owner.go | 2 +- .../pkg/handler/eventhandler.go | 130 +- .../pkg/internal/controller/controller.go | 162 +- .../internal/controller/metrics/metrics.go | 9 +- .../pkg/internal/metrics/workqueue.go | 61 +- .../pkg/internal/source/event_handler.go | 18 +- .../pkg/internal/source/kind.go | 14 +- .../pkg/log/warning_handler.go | 27 +- .../controller-runtime/pkg/manager/manager.go | 4 + .../pkg/reconcile/reconcile.go | 12 +- .../controller-runtime/pkg/source/source.go | 8 +- .../pkg/webhook/admission/multi.go | 6 + .../pkg/webhook/internal/metrics/metrics.go | 8 +- .../sigs.k8s.io/randfill/CONTRIBUTING.md | 43 + .../vendor/sigs.k8s.io/randfill/LICENSE | 202 + .../vendor/sigs.k8s.io/randfill/NOTICE | 24 + .../vendor/sigs.k8s.io/randfill/OWNERS | 8 + .../sigs.k8s.io/randfill/OWNERS_ALIASES | 14 + .../gofuzz => sigs.k8s.io/randfill}/README.md | 45 +- .../sigs.k8s.io/randfill/SECURITY_CONTACTS | 16 + .../randfill}/bytesource/bytesource.go | 0 .../sigs.k8s.io/randfill/code-of-conduct.md | 3 + .../vendor/sigs.k8s.io/randfill/randfill.go | 682 + .../structured-merge-diff/v4/merge/update.go | 50 +- .../structured-merge-diff/v4/typed/typed.go | 47 +- .../structured-merge-diff/v4/value/scalar.go | 2 +- test/scripts/install-kind.sh | 2 +- test/scripts/upgrade-ovn.sh | 2 +- 1039 files changed, 80119 insertions(+), 22573 deletions(-) create mode 100644 go-controller/vendor/github.com/blang/semver/v4/LICENSE create mode 100644 go-controller/vendor/github.com/blang/semver/v4/json.go create mode 100644 go-controller/vendor/github.com/blang/semver/v4/range.go create mode 100644 go-controller/vendor/github.com/blang/semver/v4/semver.go create mode 100644 go-controller/vendor/github.com/blang/semver/v4/sort.go create mode 100644 go-controller/vendor/github.com/blang/semver/v4/sql.go delete mode 100644 go-controller/vendor/github.com/golang/protobuf/AUTHORS delete mode 100644 go-controller/vendor/github.com/golang/protobuf/CONTRIBUTORS delete mode 100644 go-controller/vendor/github.com/golang/protobuf/proto/buffer.go delete mode 100644 go-controller/vendor/github.com/golang/protobuf/proto/defaults.go delete mode 100644 go-controller/vendor/github.com/golang/protobuf/proto/deprecated.go delete mode 100644 go-controller/vendor/github.com/golang/protobuf/proto/discard.go delete mode 100644 go-controller/vendor/github.com/golang/protobuf/proto/extensions.go delete mode 100644 go-controller/vendor/github.com/golang/protobuf/proto/properties.go delete mode 100644 go-controller/vendor/github.com/golang/protobuf/proto/proto.go delete mode 100644 go-controller/vendor/github.com/golang/protobuf/proto/registry.go delete mode 100644 go-controller/vendor/github.com/golang/protobuf/proto/text_decode.go delete mode 100644 go-controller/vendor/github.com/golang/protobuf/proto/text_encode.go delete mode 100644 go-controller/vendor/github.com/golang/protobuf/proto/wire.go delete mode 100644 go-controller/vendor/github.com/golang/protobuf/proto/wrappers.go delete mode 100644 go-controller/vendor/github.com/golang/protobuf/ptypes/any.go delete mode 100644 go-controller/vendor/github.com/golang/protobuf/ptypes/any/any.pb.go delete mode 100644 go-controller/vendor/github.com/golang/protobuf/ptypes/doc.go delete mode 100644 go-controller/vendor/github.com/golang/protobuf/ptypes/duration.go delete mode 100644 go-controller/vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go delete mode 100644 go-controller/vendor/github.com/golang/protobuf/ptypes/timestamp.go delete mode 100644 go-controller/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go create mode 100644 go-controller/vendor/github.com/google/gnostic-models/openapiv3/annotations.pb.go create mode 100644 go-controller/vendor/github.com/google/gnostic-models/openapiv3/annotations.proto delete mode 100644 go-controller/vendor/github.com/google/gofuzz/.travis.yml delete mode 100644 go-controller/vendor/github.com/google/gofuzz/CONTRIBUTING.md delete mode 100644 go-controller/vendor/github.com/google/gofuzz/fuzz.go delete mode 100644 go-controller/vendor/github.com/gorilla/websocket/tls_handshake.go delete mode 100644 go-controller/vendor/github.com/gorilla/websocket/tls_handshake_116.go delete mode 100644 go-controller/vendor/github.com/gorilla/websocket/x_net_proxy.go rename go-controller/vendor/github.com/{golang/protobuf => prometheus/client_golang/internal/github.com/golang/gddo}/LICENSE (83%) create mode 100644 go-controller/vendor/github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil/header/header.go create mode 100644 go-controller/vendor/github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil/negotiate.go create mode 100644 go-controller/vendor/github.com/prometheus/client_golang/prometheus/collectorfunc.go create mode 100644 go-controller/vendor/github.com/prometheus/client_golang/prometheus/process_collector_darwin.go create mode 100644 go-controller/vendor/github.com/prometheus/client_golang/prometheus/process_collector_mem_cgo_darwin.c create mode 100644 go-controller/vendor/github.com/prometheus/client_golang/prometheus/process_collector_mem_cgo_darwin.go create mode 100644 go-controller/vendor/github.com/prometheus/client_golang/prometheus/process_collector_mem_nocgo_darwin.go rename go-controller/vendor/github.com/prometheus/client_golang/prometheus/{process_collector_wasip1.go => process_collector_not_supported.go} (55%) rename go-controller/vendor/github.com/prometheus/client_golang/prometheus/{process_collector_other.go => process_collector_procfsenabled.go} (63%) rename go-controller/vendor/github.com/prometheus/client_golang/prometheus/{process_collector_js.go => promhttp/internal/compression.go} (70%) delete mode 100644 go-controller/vendor/github.com/prometheus/common/model/labelset_string_go120.go create mode 100644 go-controller/vendor/github.com/stretchr/testify/assert/yaml/yaml_custom.go create mode 100644 go-controller/vendor/github.com/stretchr/testify/assert/yaml/yaml_default.go create mode 100644 go-controller/vendor/github.com/stretchr/testify/assert/yaml/yaml_fail.go create mode 100644 go-controller/vendor/go.opentelemetry.io/otel/LICENSE create mode 100644 go-controller/vendor/go.opentelemetry.io/otel/attribute/README.md create mode 100644 go-controller/vendor/go.opentelemetry.io/otel/attribute/doc.go create mode 100644 go-controller/vendor/go.opentelemetry.io/otel/attribute/encoder.go create mode 100644 go-controller/vendor/go.opentelemetry.io/otel/attribute/filter.go create mode 100644 go-controller/vendor/go.opentelemetry.io/otel/attribute/iterator.go create mode 100644 go-controller/vendor/go.opentelemetry.io/otel/attribute/key.go create mode 100644 go-controller/vendor/go.opentelemetry.io/otel/attribute/kv.go create mode 100644 go-controller/vendor/go.opentelemetry.io/otel/attribute/set.go create mode 100644 go-controller/vendor/go.opentelemetry.io/otel/attribute/type_string.go create mode 100644 go-controller/vendor/go.opentelemetry.io/otel/attribute/value.go create mode 100644 go-controller/vendor/go.opentelemetry.io/otel/codes/README.md create mode 100644 go-controller/vendor/go.opentelemetry.io/otel/codes/codes.go create mode 100644 go-controller/vendor/go.opentelemetry.io/otel/codes/doc.go create mode 100644 go-controller/vendor/go.opentelemetry.io/otel/internal/attribute/attribute.go create mode 100644 go-controller/vendor/go.opentelemetry.io/otel/internal/gen.go create mode 100644 go-controller/vendor/go.opentelemetry.io/otel/internal/rawhelpers.go create mode 100644 go-controller/vendor/go.opentelemetry.io/otel/trace/LICENSE create mode 100644 go-controller/vendor/go.opentelemetry.io/otel/trace/README.md create mode 100644 go-controller/vendor/go.opentelemetry.io/otel/trace/config.go create mode 100644 go-controller/vendor/go.opentelemetry.io/otel/trace/context.go create mode 100644 go-controller/vendor/go.opentelemetry.io/otel/trace/doc.go create mode 100644 go-controller/vendor/go.opentelemetry.io/otel/trace/embedded/README.md create mode 100644 go-controller/vendor/go.opentelemetry.io/otel/trace/embedded/embedded.go create mode 100644 go-controller/vendor/go.opentelemetry.io/otel/trace/nonrecording.go create mode 100644 go-controller/vendor/go.opentelemetry.io/otel/trace/noop.go create mode 100644 go-controller/vendor/go.opentelemetry.io/otel/trace/provider.go create mode 100644 go-controller/vendor/go.opentelemetry.io/otel/trace/span.go create mode 100644 go-controller/vendor/go.opentelemetry.io/otel/trace/trace.go create mode 100644 go-controller/vendor/go.opentelemetry.io/otel/trace/tracer.go create mode 100644 go-controller/vendor/go.opentelemetry.io/otel/trace/tracestate.go create mode 100644 go-controller/vendor/google.golang.org/grpc/balancer/pickfirst/internal/internal.go create mode 100644 go-controller/vendor/google.golang.org/grpc/balancer/pickfirst/pickfirstleaf/pickfirstleaf.go create mode 100644 go-controller/vendor/google.golang.org/grpc/encoding/encoding_v2.go create mode 100644 go-controller/vendor/google.golang.org/grpc/experimental/stats/metricregistry.go create mode 100644 go-controller/vendor/google.golang.org/grpc/experimental/stats/metrics.go create mode 100644 go-controller/vendor/google.golang.org/grpc/grpclog/internal/grpclog.go create mode 100644 go-controller/vendor/google.golang.org/grpc/grpclog/internal/logger.go rename go-controller/vendor/google.golang.org/grpc/{internal/grpclog/grpclog.go => grpclog/internal/loggerv2.go} (52%) rename go-controller/vendor/google.golang.org/grpc/internal/grpclog/{prefixLogger.go => prefix_logger.go} (63%) create mode 100644 go-controller/vendor/google.golang.org/grpc/internal/stats/labels.go create mode 100644 go-controller/vendor/google.golang.org/grpc/internal/stats/metrics_recorder_list.go create mode 100644 go-controller/vendor/google.golang.org/grpc/mem/buffer_pool.go create mode 100644 go-controller/vendor/google.golang.org/grpc/mem/buffer_slice.go create mode 100644 go-controller/vendor/google.golang.org/grpc/mem/buffers.go delete mode 100644 go-controller/vendor/google.golang.org/grpc/regenerate.sh delete mode 100644 go-controller/vendor/google.golang.org/grpc/shared_buffer_pool.go delete mode 100644 go-controller/vendor/google.golang.org/protobuf/internal/editionssupport/editions.go delete mode 100644 go-controller/vendor/google.golang.org/protobuf/internal/errors/is_go112.go delete mode 100644 go-controller/vendor/google.golang.org/protobuf/internal/errors/is_go113.go create mode 100644 go-controller/vendor/google.golang.org/protobuf/internal/genid/name.go create mode 100644 go-controller/vendor/google.golang.org/protobuf/internal/impl/api_export_opaque.go create mode 100644 go-controller/vendor/google.golang.org/protobuf/internal/impl/bitmap.go create mode 100644 go-controller/vendor/google.golang.org/protobuf/internal/impl/bitmap_race.go create mode 100644 go-controller/vendor/google.golang.org/protobuf/internal/impl/codec_field_opaque.go delete mode 100644 go-controller/vendor/google.golang.org/protobuf/internal/impl/codec_map_go111.go delete mode 100644 go-controller/vendor/google.golang.org/protobuf/internal/impl/codec_map_go112.go create mode 100644 go-controller/vendor/google.golang.org/protobuf/internal/impl/codec_message_opaque.go create mode 100644 go-controller/vendor/google.golang.org/protobuf/internal/impl/lazy.go create mode 100644 go-controller/vendor/google.golang.org/protobuf/internal/impl/message_opaque.go create mode 100644 go-controller/vendor/google.golang.org/protobuf/internal/impl/message_opaque_gen.go create mode 100644 go-controller/vendor/google.golang.org/protobuf/internal/impl/message_reflect_field_gen.go create mode 100644 go-controller/vendor/google.golang.org/protobuf/internal/impl/pointer_unsafe_opaque.go create mode 100644 go-controller/vendor/google.golang.org/protobuf/internal/impl/presence.go delete mode 100644 go-controller/vendor/google.golang.org/protobuf/internal/impl/weak.go create mode 100644 go-controller/vendor/google.golang.org/protobuf/internal/protolazy/bufferreader.go create mode 100644 go-controller/vendor/google.golang.org/protobuf/internal/protolazy/lazy.go create mode 100644 go-controller/vendor/google.golang.org/protobuf/internal/protolazy/pointer_unsafe.go create mode 100644 go-controller/vendor/google.golang.org/protobuf/proto/wrapperopaque.go delete mode 100644 go-controller/vendor/google.golang.org/protobuf/reflect/protodesc/desc.go delete mode 100644 go-controller/vendor/google.golang.org/protobuf/reflect/protodesc/desc_init.go delete mode 100644 go-controller/vendor/google.golang.org/protobuf/reflect/protodesc/desc_resolve.go delete mode 100644 go-controller/vendor/google.golang.org/protobuf/reflect/protodesc/desc_validate.go delete mode 100644 go-controller/vendor/google.golang.org/protobuf/reflect/protodesc/editions.go delete mode 100644 go-controller/vendor/google.golang.org/protobuf/reflect/protodesc/proto.go delete mode 100644 go-controller/vendor/google.golang.org/protobuf/types/gofeaturespb/go_features.pb.go create mode 100644 go-controller/vendor/k8s.io/api/networking/v1/well_known_labels.go create mode 100644 go-controller/vendor/k8s.io/api/resource/v1beta1/devicetaint.go create mode 100644 go-controller/vendor/k8s.io/api/resource/v1beta2/devicetaint.go create mode 100644 go-controller/vendor/k8s.io/api/resource/v1beta2/doc.go create mode 100644 go-controller/vendor/k8s.io/api/resource/v1beta2/generated.pb.go create mode 100644 go-controller/vendor/k8s.io/api/resource/v1beta2/generated.proto create mode 100644 go-controller/vendor/k8s.io/api/resource/v1beta2/register.go create mode 100644 go-controller/vendor/k8s.io/api/resource/v1beta2/types.go create mode 100644 go-controller/vendor/k8s.io/api/resource/v1beta2/types_swagger_doc_generated.go create mode 100644 go-controller/vendor/k8s.io/api/resource/v1beta2/zz_generated.deepcopy.go create mode 100644 go-controller/vendor/k8s.io/api/resource/v1beta2/zz_generated.prerelease-lifecycle.go create mode 100644 go-controller/vendor/k8s.io/apiextensions-apiserver/pkg/features/OWNERS create mode 100644 go-controller/vendor/k8s.io/apiextensions-apiserver/pkg/features/kube_features.go create mode 100644 go-controller/vendor/k8s.io/apimachinery/pkg/api/operation/operation.go create mode 100644 go-controller/vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/collections.go create mode 100644 go-controller/vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf/collections.go create mode 100644 go-controller/vendor/k8s.io/apimachinery/pkg/util/validation/field/error_matcher.go create mode 100644 go-controller/vendor/k8s.io/apimachinery/pkg/util/validation/ip.go create mode 100644 go-controller/vendor/k8s.io/apimachinery/pkg/util/yaml/stream_reader.go rename go-controller/vendor/{github.com/google/gofuzz => k8s.io/apiserver}/LICENSE (100%) create mode 100644 go-controller/vendor/k8s.io/apiserver/pkg/features/OWNERS create mode 100644 go-controller/vendor/k8s.io/apiserver/pkg/features/kube_features.go create mode 100644 go-controller/vendor/k8s.io/apiserver/pkg/util/feature/feature_gate.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/certificates/v1beta1/clustertrustbundle.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/certificates/v1beta1/clustertrustbundlespec.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/coordination/v1beta1/leasecandidate.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/coordination/v1beta1/leasecandidatespec.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/core/v1/nodeswapstatus.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/discovery/v1/fornode.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/discovery/v1beta1/fornode.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/networking/v1/ipaddress.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/networking/v1/ipaddressspec.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/networking/v1/parentreference.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/networking/v1/servicecidr.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/networking/v1/servicecidrspec.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/networking/v1/servicecidrstatus.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha3/counter.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha3/counterset.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha3/devicecounterconsumption.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha3/devicesubrequest.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha3/devicetaint.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha3/devicetaintrule.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha3/devicetaintrulespec.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha3/devicetaintselector.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1alpha3/devicetoleration.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/counter.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/counterset.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/devicecounterconsumption.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/devicesubrequest.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/devicetaint.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta1/devicetoleration.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/allocateddevicestatus.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/allocationresult.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/celdeviceselector.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/counter.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/counterset.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/device.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/deviceallocationconfiguration.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/deviceallocationresult.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/deviceattribute.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/devicecapacity.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/deviceclaim.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/deviceclaimconfiguration.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/deviceclass.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/deviceclassconfiguration.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/deviceclassspec.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/deviceconfiguration.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/deviceconstraint.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/devicecounterconsumption.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/devicerequest.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/devicerequestallocationresult.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/deviceselector.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/devicesubrequest.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/devicetaint.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/devicetoleration.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/exactdevicerequest.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/networkdevicedata.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/opaquedeviceconfiguration.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/resourceclaim.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/resourceclaimconsumerreference.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/resourceclaimspec.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/resourceclaimstatus.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/resourceclaimtemplate.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/resourceclaimtemplatespec.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/resourcepool.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/resourceslice.go create mode 100644 go-controller/vendor/k8s.io/client-go/applyconfigurations/resource/v1beta2/resourceslicespec.go create mode 100644 go-controller/vendor/k8s.io/client-go/informers/certificates/v1beta1/clustertrustbundle.go create mode 100644 go-controller/vendor/k8s.io/client-go/informers/coordination/v1beta1/leasecandidate.go create mode 100644 go-controller/vendor/k8s.io/client-go/informers/networking/v1/ipaddress.go create mode 100644 go-controller/vendor/k8s.io/client-go/informers/networking/v1/servicecidr.go create mode 100644 go-controller/vendor/k8s.io/client-go/informers/resource/v1alpha3/devicetaintrule.go create mode 100644 go-controller/vendor/k8s.io/client-go/informers/resource/v1beta2/deviceclass.go create mode 100644 go-controller/vendor/k8s.io/client-go/informers/resource/v1beta2/interface.go create mode 100644 go-controller/vendor/k8s.io/client-go/informers/resource/v1beta2/resourceclaim.go create mode 100644 go-controller/vendor/k8s.io/client-go/informers/resource/v1beta2/resourceclaimtemplate.go create mode 100644 go-controller/vendor/k8s.io/client-go/informers/resource/v1beta2/resourceslice.go create mode 100644 go-controller/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1beta1/clustertrustbundle.go create mode 100644 go-controller/vendor/k8s.io/client-go/kubernetes/typed/certificates/v1beta1/fake/fake_clustertrustbundle.go create mode 100644 go-controller/vendor/k8s.io/client-go/kubernetes/typed/coordination/v1beta1/fake/fake_leasecandidate.go create mode 100644 go-controller/vendor/k8s.io/client-go/kubernetes/typed/coordination/v1beta1/leasecandidate.go create mode 100644 go-controller/vendor/k8s.io/client-go/kubernetes/typed/networking/v1/fake/fake_ipaddress.go create mode 100644 go-controller/vendor/k8s.io/client-go/kubernetes/typed/networking/v1/fake/fake_servicecidr.go create mode 100644 go-controller/vendor/k8s.io/client-go/kubernetes/typed/networking/v1/ipaddress.go create mode 100644 go-controller/vendor/k8s.io/client-go/kubernetes/typed/networking/v1/servicecidr.go create mode 100644 go-controller/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha3/devicetaintrule.go create mode 100644 go-controller/vendor/k8s.io/client-go/kubernetes/typed/resource/v1alpha3/fake/fake_devicetaintrule.go create mode 100644 go-controller/vendor/k8s.io/client-go/kubernetes/typed/resource/v1beta2/deviceclass.go create mode 100644 go-controller/vendor/k8s.io/client-go/kubernetes/typed/resource/v1beta2/doc.go rename go-controller/vendor/{github.com/google/gofuzz => k8s.io/client-go/kubernetes/typed/resource/v1beta2/fake}/doc.go (77%) create mode 100644 go-controller/vendor/k8s.io/client-go/kubernetes/typed/resource/v1beta2/fake/fake_deviceclass.go create mode 100644 go-controller/vendor/k8s.io/client-go/kubernetes/typed/resource/v1beta2/fake/fake_resource_client.go create mode 100644 go-controller/vendor/k8s.io/client-go/kubernetes/typed/resource/v1beta2/fake/fake_resourceclaim.go create mode 100644 go-controller/vendor/k8s.io/client-go/kubernetes/typed/resource/v1beta2/fake/fake_resourceclaimtemplate.go create mode 100644 go-controller/vendor/k8s.io/client-go/kubernetes/typed/resource/v1beta2/fake/fake_resourceslice.go create mode 100644 go-controller/vendor/k8s.io/client-go/kubernetes/typed/resource/v1beta2/generated_expansion.go create mode 100644 go-controller/vendor/k8s.io/client-go/kubernetes/typed/resource/v1beta2/resource_client.go create mode 100644 go-controller/vendor/k8s.io/client-go/kubernetes/typed/resource/v1beta2/resourceclaim.go create mode 100644 go-controller/vendor/k8s.io/client-go/kubernetes/typed/resource/v1beta2/resourceclaimtemplate.go create mode 100644 go-controller/vendor/k8s.io/client-go/kubernetes/typed/resource/v1beta2/resourceslice.go create mode 100644 go-controller/vendor/k8s.io/client-go/listers/certificates/v1beta1/clustertrustbundle.go create mode 100644 go-controller/vendor/k8s.io/client-go/listers/coordination/v1beta1/leasecandidate.go create mode 100644 go-controller/vendor/k8s.io/client-go/listers/networking/v1/ipaddress.go create mode 100644 go-controller/vendor/k8s.io/client-go/listers/networking/v1/servicecidr.go create mode 100644 go-controller/vendor/k8s.io/client-go/listers/resource/v1alpha3/devicetaintrule.go create mode 100644 go-controller/vendor/k8s.io/client-go/listers/resource/v1beta2/deviceclass.go create mode 100644 go-controller/vendor/k8s.io/client-go/listers/resource/v1beta2/expansion_generated.go create mode 100644 go-controller/vendor/k8s.io/client-go/listers/resource/v1beta2/resourceclaim.go create mode 100644 go-controller/vendor/k8s.io/client-go/listers/resource/v1beta2/resourceclaimtemplate.go create mode 100644 go-controller/vendor/k8s.io/client-go/listers/resource/v1beta2/resourceslice.go create mode 100644 go-controller/vendor/k8s.io/client-go/rest/.mockery.yaml create mode 100644 go-controller/vendor/k8s.io/client-go/tools/cache/the_real_fifo.go create mode 100644 go-controller/vendor/k8s.io/component-base/featuregate/OWNERS create mode 100644 go-controller/vendor/k8s.io/component-base/featuregate/feature_gate.go create mode 100644 go-controller/vendor/k8s.io/component-base/metrics/OWNERS create mode 100644 go-controller/vendor/k8s.io/component-base/metrics/buckets.go create mode 100644 go-controller/vendor/k8s.io/component-base/metrics/collector.go create mode 100644 go-controller/vendor/k8s.io/component-base/metrics/counter.go create mode 100644 go-controller/vendor/k8s.io/component-base/metrics/desc.go create mode 100644 go-controller/vendor/k8s.io/component-base/metrics/gauge.go create mode 100644 go-controller/vendor/k8s.io/component-base/metrics/histogram.go create mode 100644 go-controller/vendor/k8s.io/component-base/metrics/http.go create mode 100644 go-controller/vendor/k8s.io/component-base/metrics/labels.go create mode 100644 go-controller/vendor/k8s.io/component-base/metrics/legacyregistry/registry.go create mode 100644 go-controller/vendor/k8s.io/component-base/metrics/metric.go create mode 100644 go-controller/vendor/k8s.io/component-base/metrics/options.go create mode 100644 go-controller/vendor/k8s.io/component-base/metrics/opts.go create mode 100644 go-controller/vendor/k8s.io/component-base/metrics/processstarttime.go create mode 100644 go-controller/vendor/k8s.io/component-base/metrics/processstarttime_others.go create mode 100644 go-controller/vendor/k8s.io/component-base/metrics/processstarttime_windows.go create mode 100644 go-controller/vendor/k8s.io/component-base/metrics/prometheus/feature/metrics.go create mode 100644 go-controller/vendor/k8s.io/component-base/metrics/prometheusextension/timing_histogram.go create mode 100644 go-controller/vendor/k8s.io/component-base/metrics/prometheusextension/timing_histogram_vec.go create mode 100644 go-controller/vendor/k8s.io/component-base/metrics/prometheusextension/weighted_histogram.go create mode 100644 go-controller/vendor/k8s.io/component-base/metrics/prometheusextension/weighted_histogram_vec.go create mode 100644 go-controller/vendor/k8s.io/component-base/metrics/registry.go create mode 100644 go-controller/vendor/k8s.io/component-base/metrics/summary.go create mode 100644 go-controller/vendor/k8s.io/component-base/metrics/timing_histogram.go create mode 100644 go-controller/vendor/k8s.io/component-base/metrics/value.go create mode 100644 go-controller/vendor/k8s.io/component-base/metrics/version.go create mode 100644 go-controller/vendor/k8s.io/component-base/metrics/version_parser.go create mode 100644 go-controller/vendor/k8s.io/component-base/metrics/wrappers.go create mode 100644 go-controller/vendor/k8s.io/component-base/zpages/features/doc.go create mode 100644 go-controller/vendor/k8s.io/component-base/zpages/features/kube_features.go create mode 100644 go-controller/vendor/k8s.io/controller-manager/LICENSE create mode 100644 go-controller/vendor/k8s.io/controller-manager/pkg/features/OWNERS create mode 100644 go-controller/vendor/k8s.io/controller-manager/pkg/features/kube_features.go create mode 100644 go-controller/vendor/k8s.io/kubernetes/pkg/features/OWNERS create mode 100644 go-controller/vendor/k8s.io/kubernetes/pkg/features/client_adapter.go create mode 100644 go-controller/vendor/k8s.io/kubernetes/pkg/features/kube_features.go delete mode 100644 go-controller/vendor/k8s.io/utils/clock/testing/fake_clock.go delete mode 100644 go-controller/vendor/k8s.io/utils/clock/testing/simple_interval_clock.go create mode 100644 go-controller/vendor/sigs.k8s.io/randfill/CONTRIBUTING.md create mode 100644 go-controller/vendor/sigs.k8s.io/randfill/LICENSE create mode 100644 go-controller/vendor/sigs.k8s.io/randfill/NOTICE create mode 100644 go-controller/vendor/sigs.k8s.io/randfill/OWNERS create mode 100644 go-controller/vendor/sigs.k8s.io/randfill/OWNERS_ALIASES rename go-controller/vendor/{github.com/google/gofuzz => sigs.k8s.io/randfill}/README.md (53%) create mode 100644 go-controller/vendor/sigs.k8s.io/randfill/SECURITY_CONTACTS rename go-controller/vendor/{github.com/google/gofuzz => sigs.k8s.io/randfill}/bytesource/bytesource.go (100%) create mode 100644 go-controller/vendor/sigs.k8s.io/randfill/code-of-conduct.md create mode 100644 go-controller/vendor/sigs.k8s.io/randfill/randfill.go diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index cd0a35e4c3..6d56ef607d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,7 +20,7 @@ concurrency: cancel-in-progress: true env: - K8S_VERSION: v1.32.3 + K8S_VERSION: v1.33.1 KIND_CLUSTER_NAME: ovn KIND_INSTALL_INGRESS: true KIND_ALLOW_SYSTEM_WRITES: true @@ -61,7 +61,7 @@ jobs: - name: Verify uses: golangci/golangci-lint-action@v6 with: - version: v1.60.3 + version: v1.64.8 working-directory: go-controller args: --modules-download-mode=vendor --timeout=15m0s --verbose diff --git a/contrib/kind-common b/contrib/kind-common index 2a564dece0..16a8c1a894 100644 --- a/contrib/kind-common +++ b/contrib/kind-common @@ -34,7 +34,7 @@ if_error_exit() { set_common_default_params() { KIND_IMAGE=${KIND_IMAGE:-kindest/node} - K8S_VERSION=${K8S_VERSION:-v1.32.3} + K8S_VERSION=${K8S_VERSION:-v1.33.1} } run_kubectl() { diff --git a/docs/ci/ci.md b/docs/ci/ci.md index b0f98c0762..1d17671925 100644 --- a/docs/ci/ci.md +++ b/docs/ci/ci.md @@ -120,7 +120,7 @@ and set the environmental variable `K8S_VERSION` to the same value. Also make su your go directory with `export GOPATH=(...)`. ``` -K8S_VERSION=v1.32.3 +K8S_VERSION=v1.33.1 git clone --single-branch --branch $K8S_VERSION https://github.com/kubernetes/kubernetes.git $GOPATH/src/k8s.io/kubernetes/ pushd $GOPATH/src/k8s.io/kubernetes/ make WHAT="test/e2e/e2e.test vendor/github.com/onsi/ginkgo/ginkgo cmd/kubectl" diff --git a/docs/installation/launching-ovn-kubernetes-on-kind.md b/docs/installation/launching-ovn-kubernetes-on-kind.md index 1a6ae11a15..183f738884 100644 --- a/docs/installation/launching-ovn-kubernetes-on-kind.md +++ b/docs/installation/launching-ovn-kubernetes-on-kind.md @@ -375,7 +375,7 @@ sudo ln -s /usr/bin/kubectl-v1.17.3 /usr/bin/kubectl Download and install latest version of `kubectl`: ``` -$ K8S_VERSION=v1.32.3 +$ K8S_VERSION=v1.33.1 $ curl -LO https://storage.googleapis.com/kubernetes-release/release/$K8S_VERSION/bin/linux/amd64/kubectl $ chmod +x kubectl $ sudo mv kubectl /usr/bin/kubectl-$K8S_VERSION @@ -431,7 +431,7 @@ $ cd ../dist/images/ $ make fedora-image $ cd ../../contrib/ -$ PLATFORM_IPV4_SUPPORT=true PLATFORM_IPV6_SUPPORT=true K8S_VERSION=v1.32.3 ./kind.sh +$ PLATFORM_IPV4_SUPPORT=true PLATFORM_IPV6_SUPPORT=true K8S_VERSION=v1.33.1 ./kind.sh ``` Once `kind.sh` completes, setup kube config file: @@ -457,7 +457,7 @@ one (or both of) the following variables: ``` $ cd ../../contrib/ -$ KIND_IMAGE=example.com/kindest/node K8S_VERSION=v1.32.3 ./kind.sh +$ KIND_IMAGE=example.com/kindest/node K8S_VERSION=v1.33.1 ./kind.sh ``` ### Using kind local registry to deploy non ovn-k containers diff --git a/go-controller/cmd/ovnkube-trace/ovnkube-trace.go b/go-controller/cmd/ovnkube-trace/ovnkube-trace.go index 2460ff3d36..96cea038d2 100644 --- a/go-controller/cmd/ovnkube-trace/ovnkube-trace.go +++ b/go-controller/cmd/ovnkube-trace/ovnkube-trace.go @@ -15,9 +15,11 @@ import ( "strings" corev1 "k8s.io/api/core/v1" + discoveryv1 "k8s.io/api/discovery/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" corev1client "k8s.io/client-go/kubernetes/typed/core/v1" + discoveryv1client "k8s.io/client-go/kubernetes/typed/discovery/v1" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/tools/remotecommand" @@ -44,7 +46,7 @@ const ( const ( // nbdb and sbdb local socket file path and protocol string which are // used by ovnkube-trace for establishing the connection when node - // runs on its own zone in an interconnect environment. + // runs on its own zone in an interconnect environment nbdbServerSock = "unix:/var/run/ovn/ovnnb_db.sock" sbdbServerSock = "unix:/var/run/ovn/ovnsb_db.sock" sockProtocol = "unix" @@ -364,13 +366,20 @@ func getSvcInfo(coreclient *corev1client.CoreV1Client, restconfig *rest.Config, ClusterIP: clusterIPStr, } - ep, err := coreclient.Endpoints(namespace).Get(context.TODO(), svcName, metav1.GetOptions{}) + discoveryClient, err := discoveryv1client.NewForConfig(restconfig) if err != nil { - return nil, fmt.Errorf("endpoints for service %s in namespace %s not found, err: %v", svcName, namespace, err) + return nil, fmt.Errorf("failed to create discovery client: %w", err) } - klog.V(5).Infof("==> Got Endpoint %v for service %s in namespace %s\n", ep, svcName, namespace) - err = extractSubsetInfo(coreclient, restconfig, ep.Subsets, svcInfo, ovnNamespace, addressFamily) + es, err := discoveryClient.EndpointSlices(namespace).List(context.TODO(), metav1.ListOptions{ + LabelSelector: fmt.Sprintf("kubernetes.io/service-name=%s", svcName), + }) + if err != nil { + return nil, fmt.Errorf("EndpointSlices for service %s in namespace %s not found, err: %w", svcName, namespace, err) + } + klog.V(5).Infof("==> Got EndpointSlices %v for service %s in namespace %s\n", es, svcName, namespace) + + err = extractEndpointSliceInfo(coreclient, restconfig, es.Items, svcInfo, ovnNamespace, addressFamily) if err != nil { return nil, err } @@ -378,58 +387,69 @@ func getSvcInfo(coreclient *corev1client.CoreV1Client, restconfig *rest.Config, return svcInfo, err } -// extractSubsetInfo copies information from the endpoint subsets into the SvcInfo object. +// extractEndpointSliceInfo copies information from the endpoint slices into the SvcInfo object. // Modifies the svcInfo object the pointer of which is passed to it. -func extractSubsetInfo(coreclient *corev1client.CoreV1Client, restconfig *rest.Config, subsets []corev1.EndpointSubset, svcInfo *SvcInfo, ovnNamespace, addressFamily string) error { - for _, subset := range subsets { - klog.V(5).Infof("==> Trying to extract information for service %s in namespace %s from subset %v", - svcInfo.SvcName, svcInfo.SvcNamespace, subset) +// slice is *discoveryv1.EndpointSlice slices is +func extractEndpointSliceInfo(coreclient *corev1client.CoreV1Client, restconfig *rest.Config, slices []discoveryv1.EndpointSlice, svcInfo *SvcInfo, ovnNamespace, addressFamily string) error { + + for _, slice := range slices { + klog.V(5).Infof("==> Trying to extract information for service %s in namespace %s from slice %v", + svcInfo.SvcName, svcInfo.SvcNamespace, slice) - // Find a port for the subset. + // Find a port for the endpoint slice. var podPort string - for _, port := range subset.Ports { - podPort = strconv.Itoa(int(port.Port)) + for _, epPort := range slice.Ports { + if epPort.Port == nil { + klog.V(5).Infof("==> Endpoint Port is nil, skipping.") + continue // with the next port + } + podPort = strconv.Itoa(int(*epPort.Port)) if podPort == "" { - klog.V(5).Infof("==> Could not parse port %v, skipping.", port) + klog.V(5).Infof("==> Could not parse port %v, skipping.", epPort) continue // with the next port } } - // Continue with the next subset if podPort is empty. + // Continue with the next slice if podPort is empty. if podPort == "" { - continue // with the next subset + continue // with the next slice } - // Parse pod information from the subset addresses. One of the subsets must have a valid address which does not belong + // Parse pod information from the endpoint slice addresses. One of the slices must have a valid address which does not belong // to a host networked pod. - for _, epAddress := range subset.Addresses { + for _, endpoint := range slice.Endpoints { + epAddress := endpoint.Addresses + if len(epAddress) == 0 { + klog.V(5).Infof("Address is empty for endpoint. Skipping.") + continue + } // This is nil for host networked services. - if epAddress.TargetRef == nil { + if endpoint.TargetRef == nil { klog.V(5).Infof("Address %v belongs to a host networked pod. Skipping.", epAddress) continue // with the next address } - if epAddress.TargetRef.Name == "" || epAddress.TargetRef.Namespace == "" || epAddress.IP == "" { - klog.V(5).Infof("Address %v contains invalid data. podName %s, podNamespace %s, podIP %s. Skipping.", - epAddress, epAddress.TargetRef.Name, epAddress.TargetRef.Namespace, epAddress.IP) + if endpoint.TargetRef.Name == "" || endpoint.TargetRef.Namespace == "" { + klog.V(5).Infof("Address %v contains invalid data. podName %s, podNamespace %s. Skipping.", + epAddress, endpoint.TargetRef.Name, endpoint.TargetRef.Namespace) continue // with the next address } // Get info needed for the src Pod - svcPodInfo, err := getPodInfo(coreclient, restconfig, epAddress.TargetRef.Name, ovnNamespace, epAddress.TargetRef.Namespace, addressFamily) + svcPodInfo, err := getPodInfo(coreclient, restconfig, endpoint.TargetRef.Name, ovnNamespace, endpoint.TargetRef.Namespace, addressFamily) if err != nil { - klog.Exitf("Failed to get information from pod %s: %v", epAddress.TargetRef.Name, err) + klog.Exitf("Failed to get information from pod %s: %v", endpoint.TargetRef.Name, err) } klog.V(5).Infof("svcPodInfo is %s\n", svcPodInfo) // At this point, we should have found valid pod information + a port, so set them and return nil. svcInfo.PodInfo = svcPodInfo svcInfo.PodPort = podPort - klog.V(5).Infof("==> Got address and port information for service endpoint. podName: %s, podNamespace: %s, podIP: %s, podPort: %s, podNodeName: %s", + klog.V(5).Infof("==> Got address and port information for service endpoint slice. podName: %s, podNamespace: %s, podIP: %s, podPort: %s, podNodeName: %s", svcInfo.PodInfo.PodName, svcInfo.PodInfo.PodNamespace, svcInfo.PodInfo.IP, svcInfo.PodPort, svcInfo.PodInfo.NodeName) return nil } } - return fmt.Errorf("could not extract pod and port information from endpoints for service %s in namespace %s", svcInfo.SvcName, svcInfo.SvcNamespace) + return fmt.Errorf("could not extract pod and port information from endpointslice for service %s in namespace %s", svcInfo.SvcName, svcInfo.SvcNamespace) } // getPodInfo returns a pointer to a fully populated PodInfo struct, or error on failure. @@ -1222,7 +1242,6 @@ func main() { } klog.V(5).Infof("OVN Kubernetes namespace is %s", ovnNamespace) - if *dumpVRFTableIDs { nodesVRFTableIDs, err := findUserDefinedNetworkVRFTableIDs(coreclient, restconfig, ovnNamespace) if err != nil { diff --git a/go-controller/go.mod b/go-controller/go.mod index 0a4e54196b..0fb223c7e7 100644 --- a/go-controller/go.mod +++ b/go-controller/go.mod @@ -1,8 +1,8 @@ module github.com/ovn-org/ovn-kubernetes/go-controller -go 1.23.0 +go 1.24.0 -toolchain go1.23.6 +toolchain go1.24.5 require ( github.com/Microsoft/hcsshim v0.9.6 @@ -18,7 +18,7 @@ require ( github.com/go-logr/logr v1.4.2 github.com/go-logr/stdr v1.2.2 github.com/godbus/dbus/v5 v5.1.0 - github.com/google/go-cmp v0.6.0 + github.com/google/go-cmp v0.7.0 github.com/google/gopacket v1.1.19 github.com/google/uuid v1.6.0 github.com/gorilla/mux v1.8.0 @@ -39,42 +39,43 @@ require ( github.com/openshift/api v0.0.0-20231120222239-b86761094ee3 github.com/openshift/client-go v0.0.0-20231121143148-910ca30a1a9a github.com/ovn-kubernetes/libovsdb v0.8.0 - github.com/prometheus/client_golang v1.19.1 + github.com/prometheus/client_golang v1.22.0 github.com/prometheus/client_model v0.6.1 github.com/safchain/ethtool v0.3.1-0.20231027162144-83e5e0097c91 github.com/spf13/afero v1.9.5 - github.com/stretchr/testify v1.9.0 + github.com/stretchr/testify v1.10.0 github.com/urfave/cli/v2 v2.27.2 github.com/vishvananda/netlink v1.3.1-0.20250206174618-62fb240731fa golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 golang.org/x/net v0.38.0 golang.org/x/sync v0.12.0 golang.org/x/sys v0.31.0 - golang.org/x/time v0.7.0 - google.golang.org/grpc v1.65.0 + golang.org/x/time v0.9.0 + google.golang.org/grpc v1.68.1 google.golang.org/grpc/security/advancedtls v0.0.0-20240425232638-1e8b9b7fc655 - google.golang.org/protobuf v1.35.1 + google.golang.org/protobuf v1.36.5 gopkg.in/fsnotify/fsnotify.v1 v1.4.7 gopkg.in/gcfg.v1 v1.2.3 gopkg.in/natefinch/lumberjack.v2 v2.2.1 - k8s.io/api v0.32.5 - k8s.io/apimachinery v0.32.5 - k8s.io/client-go v0.32.5 - k8s.io/component-helpers v0.32.3 + k8s.io/api v0.33.3 + k8s.io/apimachinery v0.33.3 + k8s.io/client-go v0.33.3 + k8s.io/component-helpers v0.33.3 k8s.io/klog/v2 v2.130.1 - k8s.io/kubernetes v1.32.6 + k8s.io/kubernetes v1.33.3 k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 kubevirt.io/api v1.0.0-alpha.0 - sigs.k8s.io/controller-runtime v0.20.3 + sigs.k8s.io/controller-runtime v0.21.0 sigs.k8s.io/knftables v0.0.18 sigs.k8s.io/network-policy-api v0.1.5 - sigs.k8s.io/structured-merge-diff/v4 v4.4.2 + sigs.k8s.io/structured-merge-diff/v4 v4.6.0 sigs.k8s.io/yaml v1.4.0 ) require ( github.com/Microsoft/go-winio v0.6.2 // indirect github.com/beorn7/perks v1.0.1 // indirect + github.com/blang/semver/v4 v4.0.0 // indirect github.com/cenkalti/hub v1.0.1 // indirect github.com/cenkalti/rpc2 v0.0.0-20210604223624-c1acbc6ec984 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect @@ -90,12 +91,10 @@ require ( github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.4 // indirect github.com/google/btree v1.1.3 // indirect - github.com/google/gnostic-models v0.6.8 // indirect - github.com/google/gofuzz v1.2.0 // indirect + github.com/google/gnostic-models v0.6.9 // indirect github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db // indirect - github.com/gorilla/websocket v1.5.0 // indirect + github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/josharian/native v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect @@ -114,7 +113,7 @@ require ( github.com/pborman/uuid v1.2.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/common v0.55.0 // indirect + github.com/prometheus/common v0.62.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect @@ -124,23 +123,28 @@ require ( github.com/x448/float16 v0.8.4 // indirect github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect go.opencensus.io v0.24.0 // indirect + go.opentelemetry.io/otel v1.33.0 // indirect + go.opentelemetry.io/otel/trace v1.33.0 // indirect golang.org/x/crypto v0.36.0 // indirect golang.org/x/oauth2 v0.27.0 // indirect golang.org/x/term v0.30.0 // indirect golang.org/x/text v0.23.0 // indirect golang.org/x/tools v0.26.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/apiextensions-apiserver v0.32.3 // indirect - k8s.io/component-base v0.32.3 // indirect - k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f // indirect + k8s.io/apiextensions-apiserver v0.33.3 // indirect + k8s.io/apiserver v0.33.3 // indirect + k8s.io/component-base v0.33.3 // indirect + k8s.io/controller-manager v0.33.3 // indirect + k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect kubevirt.io/containerized-data-importer-api v1.55.0 // indirect kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90 // indirect sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect + sigs.k8s.io/randfill v1.0.0 // indirect ) replace ( diff --git a/go-controller/go.sum b/go-controller/go.sum index d0bde9c817..f5a40c16ac 100644 --- a/go-controller/go.sum +++ b/go-controller/go.sum @@ -98,6 +98,8 @@ github.com/bhendo/go-powershell v0.0.0-20190719160123-219e7fb4e41e/go.mod h1:f7v github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= +github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= @@ -378,8 +380,8 @@ github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= -github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= +github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw= +github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -394,8 +396,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= @@ -439,8 +441,8 @@ github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB7 github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo= +github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= @@ -506,6 +508,8 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= +github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -521,6 +525,8 @@ github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/lithammer/dedent v1.1.0 h1:VNzHMVCBNG1j0fh3OrsFRkVUwStdDArbgBWoPAffktY= github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= @@ -661,8 +667,8 @@ github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDf github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= -github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= +github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q= +github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0= github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -676,8 +682,8 @@ github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= -github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= +github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= +github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= @@ -693,8 +699,8 @@ github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoG github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -753,8 +759,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= @@ -813,6 +819,10 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/otel v1.33.0 h1:/FerN9bax5LoK51X/sI0SVYrjSE0/yUL7DpxW4K3FWw= +go.opentelemetry.io/otel v1.33.0/go.mod h1:SUUkR6csvUQl+yjReHu5uM3EtVV7MBm5FHKRlNx4I8I= +go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s= +go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -1071,8 +1081,8 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ= -golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= +golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -1208,8 +1218,8 @@ google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7 h1:2035KHhUv+EpyB+hWgJnaWKJOdX1E95w2S8Rr4uWKTs= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 h1:8ZmaLZE4XWrtU3MyClkYqqtl6Oegr3235h7jxsDyqCY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -1230,8 +1240,8 @@ google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= -google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= +google.golang.org/grpc v1.68.1 h1:oI5oTa11+ng8r8XMMN7jAOmWfPZWbYpCFaMUTACxkM0= +google.golang.org/grpc v1.68.1/go.mod h1:+q1XYFJjShcqn0QZHvCyeR4CXPA+llXIeUIfIe00waw= google.golang.org/grpc/examples v0.0.0-20201112215255-90f1b3ee835b h1:NuxyvVZoDfHZwYW9LD4GJiF5/nhiSyP4/InTrvw9Ibk= google.golang.org/grpc/examples v0.0.0-20201112215255-90f1b3ee835b/go.mod h1:IBqQ7wSUJ2Ep09a8rMWFsg4fmI2r38zwsq8a0GgxXpM= google.golang.org/grpc/security/advancedtls v0.0.0-20240425232638-1e8b9b7fc655 h1:m116OZfEvs1iB0qlYNH3M9C+t8eQj3rT+2hzn88UWnU= @@ -1249,8 +1259,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= -google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= +google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1316,35 +1326,39 @@ k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ= k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8= k8s.io/api v0.22.7/go.mod h1:7hejA1BgBEiSsWljUyRkIjj+AISXO16IwsaDgFjJsQE= k8s.io/api v0.23.3/go.mod h1:w258XdGyvCmnBj/vGzQMj6kzdufJZVUwEM1U2fRJwSQ= -k8s.io/api v0.32.5 h1:uqjjsYo1kTJr5NIcoIaP9F+TgXgADH7nKQx91FDAhtk= -k8s.io/api v0.32.5/go.mod h1:bXXFU3fGCZ/eFMZvfHZC69PeGbXEL4zzjuPVzOxHF64= -k8s.io/apiextensions-apiserver v0.32.3 h1:4D8vy+9GWerlErCwVIbcQjsWunF9SUGNu7O7hiQTyPY= -k8s.io/apiextensions-apiserver v0.32.3/go.mod h1:8YwcvVRMVzw0r1Stc7XfGAzB/SIVLunqApySV5V7Dss= +k8s.io/api v0.33.3 h1:SRd5t//hhkI1buzxb288fy2xvjubstenEKL9K51KBI8= +k8s.io/api v0.33.3/go.mod h1:01Y/iLUjNBM3TAvypct7DIj0M0NIZc+PzAHCIo0CYGE= +k8s.io/apiextensions-apiserver v0.33.3 h1:qmOcAHN6DjfD0v9kxL5udB27SRP6SG/MTopmge3MwEs= +k8s.io/apiextensions-apiserver v0.33.3/go.mod h1:oROuctgo27mUsyp9+Obahos6CWcMISSAPzQ77CAQGz8= k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc= k8s.io/apimachinery v0.22.7/go.mod h1:ZvVLP5iLhwVFg2Yx9Gh5W0um0DUauExbRhe+2Z8I1EU= k8s.io/apimachinery v0.23.3/go.mod h1:BEuFMMBaIbcOqVIJqNZJXGFTP4W6AycEpb5+m/97hrM= -k8s.io/apimachinery v0.32.5 h1:6We3aJ6crC0ap8EhsEXcgX3LpI6SEjubpiOMXLROwPM= -k8s.io/apimachinery v0.32.5/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE= +k8s.io/apimachinery v0.33.3 h1:4ZSrmNa0c/ZpZJhAgRdcsFcZOw1PQU1bALVQ0B3I5LA= +k8s.io/apimachinery v0.33.3/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM= k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU= k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM= k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q= +k8s.io/apiserver v0.33.3 h1:Wv0hGc+QFdMJB4ZSiHrCgN3zL3QRatu56+rpccKC3J4= +k8s.io/apiserver v0.33.3/go.mod h1:05632ifFEe6TxwjdAIrwINHWE2hLwyADFk5mBsQa15E= k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y= k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k= k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0= k8s.io/client-go v0.22.7/go.mod h1:pGU/tWSzzvsYT7M3npHhoZ3Jh9qJTTIvFvDtWuW31dw= -k8s.io/client-go v0.32.5 h1:huFmQMzgWu0z4kbWsuZci+Gt4Fo72I4CcrvhToZ/Qp0= -k8s.io/client-go v0.32.5/go.mod h1:Qchw6f9WIVrur7DKojAHpRgGLcANT0RLIvF39Jz58xA= +k8s.io/client-go v0.33.3 h1:M5AfDnKfYmVJif92ngN532gFqakcGi6RvaOF16efrpA= +k8s.io/client-go v0.33.3/go.mod h1:luqKBQggEf3shbxHY4uVENAxrDISLOarxpTKMiUuujg= k8s.io/code-generator v0.22.7/go.mod h1:iOZwYADSgFPNGWfqHFfg1V0TNJnl1t0WyZluQp4baqU= k8s.io/code-generator v0.23.3/go.mod h1:S0Q1JVA+kSzTI1oUvbKAxZY/DYbA/ZUb4Uknog12ETk= k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk= k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI= k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM= -k8s.io/component-base v0.32.3 h1:98WJvvMs3QZ2LYHBzvltFSeJjEx7t5+8s71P7M74u8k= -k8s.io/component-base v0.32.3/go.mod h1:LWi9cR+yPAv7cu2X9rZanTiFKB2kHA+JjmhkKjCZRpI= -k8s.io/component-helpers v0.32.3 h1:9veHpOGTPLluqU4hAu5IPOwkOIZiGAJUhHndfVc5FT4= -k8s.io/component-helpers v0.32.3/go.mod h1:utTBXk8lhkJewBKNuNf32Xl3KT/0VV19DmiXU/SV4Ao= +k8s.io/component-base v0.33.3 h1:mlAuyJqyPlKZM7FyaoM/LcunZaaY353RXiOd2+B5tGA= +k8s.io/component-base v0.33.3/go.mod h1:ktBVsBzkI3imDuxYXmVxZ2zxJnYTZ4HAsVj9iF09qp4= +k8s.io/component-helpers v0.33.3 h1:fjWVORSQfI0WKzPeIFSju/gMD9sybwXBJ7oPbqQu6eM= +k8s.io/component-helpers v0.33.3/go.mod h1:7iwv+Y9Guw6X4RrnNQOyQlXcvJrVjPveHVqUA5dm31c= +k8s.io/controller-manager v0.33.3 h1:OItg5te3ixRw9MFko5KW2ed4ogBbwnJfrS4mCXixbsg= +k8s.io/controller-manager v0.33.3/go.mod h1:sH/I5CXliIc+3bnEjdalgSTJ/3fJhIHrDA3sOwTNgxM= k8s.io/cri-api v0.17.3/go.mod h1:X1sbHmuXhwaHs9xxYffLqJogVsnI+f6cPRcgPel7ywM= k8s.io/cri-api v0.20.1/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= k8s.io/cri-api v0.20.4/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= @@ -1365,10 +1379,10 @@ k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAG k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65/go.mod h1:sX9MT8g7NVZM5lVL/j8QyCCJe8YSMW30QvGZWaCIDIk= k8s.io/kube-openapi v0.0.0-20220124234850-424119656bbf/go.mod h1:sX9MT8g7NVZM5lVL/j8QyCCJe8YSMW30QvGZWaCIDIk= -k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f h1:GA7//TjRY9yWGy1poLzYYJJ4JRdzg3+O6e8I+e+8T5Y= -k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f/go.mod h1:R/HEjbvWI0qdfb8viZUeVZm0X6IZnxAydC7YU42CMw4= -k8s.io/kubernetes v1.32.6 h1:tp1gRjOqZjaoFBek5PN6eSmODdS1QRrH5UKiFP8ZByg= -k8s.io/kubernetes v1.32.6/go.mod h1:REY0Gok66BTTrbGyZaFMNKO9JhxvgBDW9B7aksWRFoY= +k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff h1:/usPimJzUKKu+m+TE36gUyGcf03XZEP0ZIKgKj35LS4= +k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8= +k8s.io/kubernetes v1.33.3 h1:dBx5Z2ZhR8kNzAwCoCz4j1niUbUrNUDVxeSj4/Ienu0= +k8s.io/kubernetes v1.33.3/go.mod h1:nrt8sldmckKz2fCZhgRX3SKfS2e+CzXATPv6ITNkU00= k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20211116205334-6203023598ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= @@ -1385,8 +1399,8 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= -sigs.k8s.io/controller-runtime v0.20.3 h1:I6Ln8JfQjHH7JbtCD2HCYHoIzajoRxPNuvhvcDbZgkI= -sigs.k8s.io/controller-runtime v0.20.3/go.mod h1:xg2XB0K5ShQzAgsoujxuKN4LNXR2LfwwHsPj7Iaw+XY= +sigs.k8s.io/controller-runtime v0.21.0 h1:CYfjpEuicjUecRk+KAeyYh+ouUBn4llGyDYytIGcJS8= +sigs.k8s.io/controller-runtime v0.21.0/go.mod h1:OSg14+F65eWqIu4DceX7k/+QRAbTTvxeQSNSOQpukWM= sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6/go.mod h1:p4QtZmO4uMYipTQNzagwnNoseA6OxSUutVw05NhYDRs= sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8= sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo= @@ -1394,11 +1408,14 @@ sigs.k8s.io/knftables v0.0.18 h1:6Duvmu0s/HwGifKrtl6G3AyAPYlWiZqTgS8bkVMiyaE= sigs.k8s.io/knftables v0.0.18/go.mod h1:f/5ZLKYEUPUhVjUCg6l80ACdL7CIIyeL0DxfgojGRTk= sigs.k8s.io/network-policy-api v0.1.5 h1:xyS7VAaM9EfyB428oFk7WjWaCK6B129i+ILUF4C8l6E= sigs.k8s.io/network-policy-api v0.1.5/go.mod h1:D7Nkr43VLNd7iYryemnj8qf0N/WjBzTZDxYA+g4u1/Y= +sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= +sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= +sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= -sigs.k8s.io/structured-merge-diff/v4 v4.4.2 h1:MdmvkGuXi/8io6ixD5wud3vOLwc1rj0aNqRlpuvjmwA= -sigs.k8s.io/structured-merge-diff/v4 v4.4.2/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4= +sigs.k8s.io/structured-merge-diff/v4 v4.6.0 h1:IUA9nvMmnKWcj5jl84xn+T5MnlZKThmUW1TdblaLVAc= +sigs.k8s.io/structured-merge-diff/v4 v4.6.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/go-controller/hack/lint.sh b/go-controller/hack/lint.sh index 57f4695827..92863e6b5c 100755 --- a/go-controller/hack/lint.sh +++ b/go-controller/hack/lint.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -VERSION=v1.60.3 +VERSION=v1.64.8 extra_flags="" if [ "$#" -ne 1 ]; then if [ "$#" -eq 2 ] && [ "$2" == "fix" ]; then diff --git a/go-controller/pkg/node/controllers/egressip/egressip_test.go b/go-controller/pkg/node/controllers/egressip/egressip_test.go index b8a0a6d6a1..7de412fdc2 100644 --- a/go-controller/pkg/node/controllers/egressip/egressip_test.go +++ b/go-controller/pkg/node/controllers/egressip/egressip_test.go @@ -29,7 +29,6 @@ import ( "k8s.io/client-go/kubernetes/fake" "k8s.io/client-go/tools/cache" utiliptables "k8s.io/kubernetes/pkg/util/iptables" - kexec "k8s.io/utils/exec" utilnet "k8s.io/utils/net" ovnconfig "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/config" @@ -170,8 +169,8 @@ func setupFakeNode(nodeInitialConfig nodeConfig) (ns.NetNS, error) { } } // adding IPTable rules - ipTableV4Client := utiliptables.New(kexec.New(), utiliptables.ProtocolIPv4) - ipTableV6Client := utiliptables.New(kexec.New(), utiliptables.ProtocolIPv6) + ipTableV4Client := utiliptables.New(utiliptables.ProtocolIPv4) + ipTableV6Client := utiliptables.New(utiliptables.ProtocolIPv6) var ipTableClient utiliptables.Interface for _, iptableRule := range nodeInitialConfig.iptableRules { if len(iptableRule.Args) != 0 { diff --git a/go-controller/pkg/node/iptables/iptables_manager.go b/go-controller/pkg/node/iptables/iptables_manager.go index b84516b9a1..1d8f31f1b0 100644 --- a/go-controller/pkg/node/iptables/iptables_manager.go +++ b/go-controller/pkg/node/iptables/iptables_manager.go @@ -67,8 +67,8 @@ func NewController() *Controller { return &Controller{ store: make(map[rulesIndex]rules, 0), mu: &sync.Mutex{}, - iptV4: iptables.New(kexec.New(), iptables.ProtocolIPv4), - iptV6: iptables.New(kexec.New(), iptables.ProtocolIPv6), + iptV4: iptables.New(iptables.ProtocolIPv4), + iptV6: iptables.New(iptables.ProtocolIPv6), } } diff --git a/go-controller/pkg/util/multi_network_test.go b/go-controller/pkg/util/multi_network_test.go index 6b2220ef25..ab6eacf5d8 100644 --- a/go-controller/pkg/util/multi_network_test.go +++ b/go-controller/pkg/util/multi_network_test.go @@ -194,7 +194,7 @@ func TestParseNetconf(t *testing.T) { "ipam": "this is wrong" } `, - expectedError: fmt.Errorf("error parsing Network Attachment Definition ns1/nad1: json: cannot unmarshal string into Go struct field NetConf.ipam of type types.IPAM"), + expectedError: fmt.Errorf("error parsing Network Attachment Definition ns1/nad1: json: cannot unmarshal string into Go struct field NetConf.NetConf.ipam of type types.IPAM"), }, { desc: "attachment definition with IPAM key defined", diff --git a/go-controller/vendor/github.com/blang/semver/v4/LICENSE b/go-controller/vendor/github.com/blang/semver/v4/LICENSE new file mode 100644 index 0000000000..5ba5c86fcb --- /dev/null +++ b/go-controller/vendor/github.com/blang/semver/v4/LICENSE @@ -0,0 +1,22 @@ +The MIT License + +Copyright (c) 2014 Benedikt Lang + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/go-controller/vendor/github.com/blang/semver/v4/json.go b/go-controller/vendor/github.com/blang/semver/v4/json.go new file mode 100644 index 0000000000..a74bf7c449 --- /dev/null +++ b/go-controller/vendor/github.com/blang/semver/v4/json.go @@ -0,0 +1,23 @@ +package semver + +import ( + "encoding/json" +) + +// MarshalJSON implements the encoding/json.Marshaler interface. +func (v Version) MarshalJSON() ([]byte, error) { + return json.Marshal(v.String()) +} + +// UnmarshalJSON implements the encoding/json.Unmarshaler interface. +func (v *Version) UnmarshalJSON(data []byte) (err error) { + var versionString string + + if err = json.Unmarshal(data, &versionString); err != nil { + return + } + + *v, err = Parse(versionString) + + return +} diff --git a/go-controller/vendor/github.com/blang/semver/v4/range.go b/go-controller/vendor/github.com/blang/semver/v4/range.go new file mode 100644 index 0000000000..95f7139b97 --- /dev/null +++ b/go-controller/vendor/github.com/blang/semver/v4/range.go @@ -0,0 +1,416 @@ +package semver + +import ( + "fmt" + "strconv" + "strings" + "unicode" +) + +type wildcardType int + +const ( + noneWildcard wildcardType = iota + majorWildcard wildcardType = 1 + minorWildcard wildcardType = 2 + patchWildcard wildcardType = 3 +) + +func wildcardTypefromInt(i int) wildcardType { + switch i { + case 1: + return majorWildcard + case 2: + return minorWildcard + case 3: + return patchWildcard + default: + return noneWildcard + } +} + +type comparator func(Version, Version) bool + +var ( + compEQ comparator = func(v1 Version, v2 Version) bool { + return v1.Compare(v2) == 0 + } + compNE = func(v1 Version, v2 Version) bool { + return v1.Compare(v2) != 0 + } + compGT = func(v1 Version, v2 Version) bool { + return v1.Compare(v2) == 1 + } + compGE = func(v1 Version, v2 Version) bool { + return v1.Compare(v2) >= 0 + } + compLT = func(v1 Version, v2 Version) bool { + return v1.Compare(v2) == -1 + } + compLE = func(v1 Version, v2 Version) bool { + return v1.Compare(v2) <= 0 + } +) + +type versionRange struct { + v Version + c comparator +} + +// rangeFunc creates a Range from the given versionRange. +func (vr *versionRange) rangeFunc() Range { + return Range(func(v Version) bool { + return vr.c(v, vr.v) + }) +} + +// Range represents a range of versions. +// A Range can be used to check if a Version satisfies it: +// +// range, err := semver.ParseRange(">1.0.0 <2.0.0") +// range(semver.MustParse("1.1.1") // returns true +type Range func(Version) bool + +// OR combines the existing Range with another Range using logical OR. +func (rf Range) OR(f Range) Range { + return Range(func(v Version) bool { + return rf(v) || f(v) + }) +} + +// AND combines the existing Range with another Range using logical AND. +func (rf Range) AND(f Range) Range { + return Range(func(v Version) bool { + return rf(v) && f(v) + }) +} + +// ParseRange parses a range and returns a Range. +// If the range could not be parsed an error is returned. +// +// Valid ranges are: +// - "<1.0.0" +// - "<=1.0.0" +// - ">1.0.0" +// - ">=1.0.0" +// - "1.0.0", "=1.0.0", "==1.0.0" +// - "!1.0.0", "!=1.0.0" +// +// A Range can consist of multiple ranges separated by space: +// Ranges can be linked by logical AND: +// - ">1.0.0 <2.0.0" would match between both ranges, so "1.1.1" and "1.8.7" but not "1.0.0" or "2.0.0" +// - ">1.0.0 <3.0.0 !2.0.3-beta.2" would match every version between 1.0.0 and 3.0.0 except 2.0.3-beta.2 +// +// Ranges can also be linked by logical OR: +// - "<2.0.0 || >=3.0.0" would match "1.x.x" and "3.x.x" but not "2.x.x" +// +// AND has a higher precedence than OR. It's not possible to use brackets. +// +// Ranges can be combined by both AND and OR +// +// - `>1.0.0 <2.0.0 || >3.0.0 !4.2.1` would match `1.2.3`, `1.9.9`, `3.1.1`, but not `4.2.1`, `2.1.1` +func ParseRange(s string) (Range, error) { + parts := splitAndTrim(s) + orParts, err := splitORParts(parts) + if err != nil { + return nil, err + } + expandedParts, err := expandWildcardVersion(orParts) + if err != nil { + return nil, err + } + var orFn Range + for _, p := range expandedParts { + var andFn Range + for _, ap := range p { + opStr, vStr, err := splitComparatorVersion(ap) + if err != nil { + return nil, err + } + vr, err := buildVersionRange(opStr, vStr) + if err != nil { + return nil, fmt.Errorf("Could not parse Range %q: %s", ap, err) + } + rf := vr.rangeFunc() + + // Set function + if andFn == nil { + andFn = rf + } else { // Combine with existing function + andFn = andFn.AND(rf) + } + } + if orFn == nil { + orFn = andFn + } else { + orFn = orFn.OR(andFn) + } + + } + return orFn, nil +} + +// splitORParts splits the already cleaned parts by '||'. +// Checks for invalid positions of the operator and returns an +// error if found. +func splitORParts(parts []string) ([][]string, error) { + var ORparts [][]string + last := 0 + for i, p := range parts { + if p == "||" { + if i == 0 { + return nil, fmt.Errorf("First element in range is '||'") + } + ORparts = append(ORparts, parts[last:i]) + last = i + 1 + } + } + if last == len(parts) { + return nil, fmt.Errorf("Last element in range is '||'") + } + ORparts = append(ORparts, parts[last:]) + return ORparts, nil +} + +// buildVersionRange takes a slice of 2: operator and version +// and builds a versionRange, otherwise an error. +func buildVersionRange(opStr, vStr string) (*versionRange, error) { + c := parseComparator(opStr) + if c == nil { + return nil, fmt.Errorf("Could not parse comparator %q in %q", opStr, strings.Join([]string{opStr, vStr}, "")) + } + v, err := Parse(vStr) + if err != nil { + return nil, fmt.Errorf("Could not parse version %q in %q: %s", vStr, strings.Join([]string{opStr, vStr}, ""), err) + } + + return &versionRange{ + v: v, + c: c, + }, nil + +} + +// inArray checks if a byte is contained in an array of bytes +func inArray(s byte, list []byte) bool { + for _, el := range list { + if el == s { + return true + } + } + return false +} + +// splitAndTrim splits a range string by spaces and cleans whitespaces +func splitAndTrim(s string) (result []string) { + last := 0 + var lastChar byte + excludeFromSplit := []byte{'>', '<', '='} + for i := 0; i < len(s); i++ { + if s[i] == ' ' && !inArray(lastChar, excludeFromSplit) { + if last < i-1 { + result = append(result, s[last:i]) + } + last = i + 1 + } else if s[i] != ' ' { + lastChar = s[i] + } + } + if last < len(s)-1 { + result = append(result, s[last:]) + } + + for i, v := range result { + result[i] = strings.Replace(v, " ", "", -1) + } + + // parts := strings.Split(s, " ") + // for _, x := range parts { + // if s := strings.TrimSpace(x); len(s) != 0 { + // result = append(result, s) + // } + // } + return +} + +// splitComparatorVersion splits the comparator from the version. +// Input must be free of leading or trailing spaces. +func splitComparatorVersion(s string) (string, string, error) { + i := strings.IndexFunc(s, unicode.IsDigit) + if i == -1 { + return "", "", fmt.Errorf("Could not get version from string: %q", s) + } + return strings.TrimSpace(s[0:i]), s[i:], nil +} + +// getWildcardType will return the type of wildcard that the +// passed version contains +func getWildcardType(vStr string) wildcardType { + parts := strings.Split(vStr, ".") + nparts := len(parts) + wildcard := parts[nparts-1] + + possibleWildcardType := wildcardTypefromInt(nparts) + if wildcard == "x" { + return possibleWildcardType + } + + return noneWildcard +} + +// createVersionFromWildcard will convert a wildcard version +// into a regular version, replacing 'x's with '0's, handling +// special cases like '1.x.x' and '1.x' +func createVersionFromWildcard(vStr string) string { + // handle 1.x.x + vStr2 := strings.Replace(vStr, ".x.x", ".x", 1) + vStr2 = strings.Replace(vStr2, ".x", ".0", 1) + parts := strings.Split(vStr2, ".") + + // handle 1.x + if len(parts) == 2 { + return vStr2 + ".0" + } + + return vStr2 +} + +// incrementMajorVersion will increment the major version +// of the passed version +func incrementMajorVersion(vStr string) (string, error) { + parts := strings.Split(vStr, ".") + i, err := strconv.Atoi(parts[0]) + if err != nil { + return "", err + } + parts[0] = strconv.Itoa(i + 1) + + return strings.Join(parts, "."), nil +} + +// incrementMajorVersion will increment the minor version +// of the passed version +func incrementMinorVersion(vStr string) (string, error) { + parts := strings.Split(vStr, ".") + i, err := strconv.Atoi(parts[1]) + if err != nil { + return "", err + } + parts[1] = strconv.Itoa(i + 1) + + return strings.Join(parts, "."), nil +} + +// expandWildcardVersion will expand wildcards inside versions +// following these rules: +// +// * when dealing with patch wildcards: +// >= 1.2.x will become >= 1.2.0 +// <= 1.2.x will become < 1.3.0 +// > 1.2.x will become >= 1.3.0 +// < 1.2.x will become < 1.2.0 +// != 1.2.x will become < 1.2.0 >= 1.3.0 +// +// * when dealing with minor wildcards: +// >= 1.x will become >= 1.0.0 +// <= 1.x will become < 2.0.0 +// > 1.x will become >= 2.0.0 +// < 1.0 will become < 1.0.0 +// != 1.x will become < 1.0.0 >= 2.0.0 +// +// * when dealing with wildcards without +// version operator: +// 1.2.x will become >= 1.2.0 < 1.3.0 +// 1.x will become >= 1.0.0 < 2.0.0 +func expandWildcardVersion(parts [][]string) ([][]string, error) { + var expandedParts [][]string + for _, p := range parts { + var newParts []string + for _, ap := range p { + if strings.Contains(ap, "x") { + opStr, vStr, err := splitComparatorVersion(ap) + if err != nil { + return nil, err + } + + versionWildcardType := getWildcardType(vStr) + flatVersion := createVersionFromWildcard(vStr) + + var resultOperator string + var shouldIncrementVersion bool + switch opStr { + case ">": + resultOperator = ">=" + shouldIncrementVersion = true + case ">=": + resultOperator = ">=" + case "<": + resultOperator = "<" + case "<=": + resultOperator = "<" + shouldIncrementVersion = true + case "", "=", "==": + newParts = append(newParts, ">="+flatVersion) + resultOperator = "<" + shouldIncrementVersion = true + case "!=", "!": + newParts = append(newParts, "<"+flatVersion) + resultOperator = ">=" + shouldIncrementVersion = true + } + + var resultVersion string + if shouldIncrementVersion { + switch versionWildcardType { + case patchWildcard: + resultVersion, _ = incrementMinorVersion(flatVersion) + case minorWildcard: + resultVersion, _ = incrementMajorVersion(flatVersion) + } + } else { + resultVersion = flatVersion + } + + ap = resultOperator + resultVersion + } + newParts = append(newParts, ap) + } + expandedParts = append(expandedParts, newParts) + } + + return expandedParts, nil +} + +func parseComparator(s string) comparator { + switch s { + case "==": + fallthrough + case "": + fallthrough + case "=": + return compEQ + case ">": + return compGT + case ">=": + return compGE + case "<": + return compLT + case "<=": + return compLE + case "!": + fallthrough + case "!=": + return compNE + } + + return nil +} + +// MustParseRange is like ParseRange but panics if the range cannot be parsed. +func MustParseRange(s string) Range { + r, err := ParseRange(s) + if err != nil { + panic(`semver: ParseRange(` + s + `): ` + err.Error()) + } + return r +} diff --git a/go-controller/vendor/github.com/blang/semver/v4/semver.go b/go-controller/vendor/github.com/blang/semver/v4/semver.go new file mode 100644 index 0000000000..307de610f9 --- /dev/null +++ b/go-controller/vendor/github.com/blang/semver/v4/semver.go @@ -0,0 +1,476 @@ +package semver + +import ( + "errors" + "fmt" + "strconv" + "strings" +) + +const ( + numbers string = "0123456789" + alphas = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-" + alphanum = alphas + numbers +) + +// SpecVersion is the latest fully supported spec version of semver +var SpecVersion = Version{ + Major: 2, + Minor: 0, + Patch: 0, +} + +// Version represents a semver compatible version +type Version struct { + Major uint64 + Minor uint64 + Patch uint64 + Pre []PRVersion + Build []string //No Precedence +} + +// Version to string +func (v Version) String() string { + b := make([]byte, 0, 5) + b = strconv.AppendUint(b, v.Major, 10) + b = append(b, '.') + b = strconv.AppendUint(b, v.Minor, 10) + b = append(b, '.') + b = strconv.AppendUint(b, v.Patch, 10) + + if len(v.Pre) > 0 { + b = append(b, '-') + b = append(b, v.Pre[0].String()...) + + for _, pre := range v.Pre[1:] { + b = append(b, '.') + b = append(b, pre.String()...) + } + } + + if len(v.Build) > 0 { + b = append(b, '+') + b = append(b, v.Build[0]...) + + for _, build := range v.Build[1:] { + b = append(b, '.') + b = append(b, build...) + } + } + + return string(b) +} + +// FinalizeVersion discards prerelease and build number and only returns +// major, minor and patch number. +func (v Version) FinalizeVersion() string { + b := make([]byte, 0, 5) + b = strconv.AppendUint(b, v.Major, 10) + b = append(b, '.') + b = strconv.AppendUint(b, v.Minor, 10) + b = append(b, '.') + b = strconv.AppendUint(b, v.Patch, 10) + return string(b) +} + +// Equals checks if v is equal to o. +func (v Version) Equals(o Version) bool { + return (v.Compare(o) == 0) +} + +// EQ checks if v is equal to o. +func (v Version) EQ(o Version) bool { + return (v.Compare(o) == 0) +} + +// NE checks if v is not equal to o. +func (v Version) NE(o Version) bool { + return (v.Compare(o) != 0) +} + +// GT checks if v is greater than o. +func (v Version) GT(o Version) bool { + return (v.Compare(o) == 1) +} + +// GTE checks if v is greater than or equal to o. +func (v Version) GTE(o Version) bool { + return (v.Compare(o) >= 0) +} + +// GE checks if v is greater than or equal to o. +func (v Version) GE(o Version) bool { + return (v.Compare(o) >= 0) +} + +// LT checks if v is less than o. +func (v Version) LT(o Version) bool { + return (v.Compare(o) == -1) +} + +// LTE checks if v is less than or equal to o. +func (v Version) LTE(o Version) bool { + return (v.Compare(o) <= 0) +} + +// LE checks if v is less than or equal to o. +func (v Version) LE(o Version) bool { + return (v.Compare(o) <= 0) +} + +// Compare compares Versions v to o: +// -1 == v is less than o +// 0 == v is equal to o +// 1 == v is greater than o +func (v Version) Compare(o Version) int { + if v.Major != o.Major { + if v.Major > o.Major { + return 1 + } + return -1 + } + if v.Minor != o.Minor { + if v.Minor > o.Minor { + return 1 + } + return -1 + } + if v.Patch != o.Patch { + if v.Patch > o.Patch { + return 1 + } + return -1 + } + + // Quick comparison if a version has no prerelease versions + if len(v.Pre) == 0 && len(o.Pre) == 0 { + return 0 + } else if len(v.Pre) == 0 && len(o.Pre) > 0 { + return 1 + } else if len(v.Pre) > 0 && len(o.Pre) == 0 { + return -1 + } + + i := 0 + for ; i < len(v.Pre) && i < len(o.Pre); i++ { + if comp := v.Pre[i].Compare(o.Pre[i]); comp == 0 { + continue + } else if comp == 1 { + return 1 + } else { + return -1 + } + } + + // If all pr versions are the equal but one has further prversion, this one greater + if i == len(v.Pre) && i == len(o.Pre) { + return 0 + } else if i == len(v.Pre) && i < len(o.Pre) { + return -1 + } else { + return 1 + } + +} + +// IncrementPatch increments the patch version +func (v *Version) IncrementPatch() error { + v.Patch++ + return nil +} + +// IncrementMinor increments the minor version +func (v *Version) IncrementMinor() error { + v.Minor++ + v.Patch = 0 + return nil +} + +// IncrementMajor increments the major version +func (v *Version) IncrementMajor() error { + v.Major++ + v.Minor = 0 + v.Patch = 0 + return nil +} + +// Validate validates v and returns error in case +func (v Version) Validate() error { + // Major, Minor, Patch already validated using uint64 + + for _, pre := range v.Pre { + if !pre.IsNum { //Numeric prerelease versions already uint64 + if len(pre.VersionStr) == 0 { + return fmt.Errorf("Prerelease can not be empty %q", pre.VersionStr) + } + if !containsOnly(pre.VersionStr, alphanum) { + return fmt.Errorf("Invalid character(s) found in prerelease %q", pre.VersionStr) + } + } + } + + for _, build := range v.Build { + if len(build) == 0 { + return fmt.Errorf("Build meta data can not be empty %q", build) + } + if !containsOnly(build, alphanum) { + return fmt.Errorf("Invalid character(s) found in build meta data %q", build) + } + } + + return nil +} + +// New is an alias for Parse and returns a pointer, parses version string and returns a validated Version or error +func New(s string) (*Version, error) { + v, err := Parse(s) + vp := &v + return vp, err +} + +// Make is an alias for Parse, parses version string and returns a validated Version or error +func Make(s string) (Version, error) { + return Parse(s) +} + +// ParseTolerant allows for certain version specifications that do not strictly adhere to semver +// specs to be parsed by this library. It does so by normalizing versions before passing them to +// Parse(). It currently trims spaces, removes a "v" prefix, adds a 0 patch number to versions +// with only major and minor components specified, and removes leading 0s. +func ParseTolerant(s string) (Version, error) { + s = strings.TrimSpace(s) + s = strings.TrimPrefix(s, "v") + + // Split into major.minor.(patch+pr+meta) + parts := strings.SplitN(s, ".", 3) + // Remove leading zeros. + for i, p := range parts { + if len(p) > 1 { + p = strings.TrimLeft(p, "0") + if len(p) == 0 || !strings.ContainsAny(p[0:1], "0123456789") { + p = "0" + p + } + parts[i] = p + } + } + // Fill up shortened versions. + if len(parts) < 3 { + if strings.ContainsAny(parts[len(parts)-1], "+-") { + return Version{}, errors.New("Short version cannot contain PreRelease/Build meta data") + } + for len(parts) < 3 { + parts = append(parts, "0") + } + } + s = strings.Join(parts, ".") + + return Parse(s) +} + +// Parse parses version string and returns a validated Version or error +func Parse(s string) (Version, error) { + if len(s) == 0 { + return Version{}, errors.New("Version string empty") + } + + // Split into major.minor.(patch+pr+meta) + parts := strings.SplitN(s, ".", 3) + if len(parts) != 3 { + return Version{}, errors.New("No Major.Minor.Patch elements found") + } + + // Major + if !containsOnly(parts[0], numbers) { + return Version{}, fmt.Errorf("Invalid character(s) found in major number %q", parts[0]) + } + if hasLeadingZeroes(parts[0]) { + return Version{}, fmt.Errorf("Major number must not contain leading zeroes %q", parts[0]) + } + major, err := strconv.ParseUint(parts[0], 10, 64) + if err != nil { + return Version{}, err + } + + // Minor + if !containsOnly(parts[1], numbers) { + return Version{}, fmt.Errorf("Invalid character(s) found in minor number %q", parts[1]) + } + if hasLeadingZeroes(parts[1]) { + return Version{}, fmt.Errorf("Minor number must not contain leading zeroes %q", parts[1]) + } + minor, err := strconv.ParseUint(parts[1], 10, 64) + if err != nil { + return Version{}, err + } + + v := Version{} + v.Major = major + v.Minor = minor + + var build, prerelease []string + patchStr := parts[2] + + if buildIndex := strings.IndexRune(patchStr, '+'); buildIndex != -1 { + build = strings.Split(patchStr[buildIndex+1:], ".") + patchStr = patchStr[:buildIndex] + } + + if preIndex := strings.IndexRune(patchStr, '-'); preIndex != -1 { + prerelease = strings.Split(patchStr[preIndex+1:], ".") + patchStr = patchStr[:preIndex] + } + + if !containsOnly(patchStr, numbers) { + return Version{}, fmt.Errorf("Invalid character(s) found in patch number %q", patchStr) + } + if hasLeadingZeroes(patchStr) { + return Version{}, fmt.Errorf("Patch number must not contain leading zeroes %q", patchStr) + } + patch, err := strconv.ParseUint(patchStr, 10, 64) + if err != nil { + return Version{}, err + } + + v.Patch = patch + + // Prerelease + for _, prstr := range prerelease { + parsedPR, err := NewPRVersion(prstr) + if err != nil { + return Version{}, err + } + v.Pre = append(v.Pre, parsedPR) + } + + // Build meta data + for _, str := range build { + if len(str) == 0 { + return Version{}, errors.New("Build meta data is empty") + } + if !containsOnly(str, alphanum) { + return Version{}, fmt.Errorf("Invalid character(s) found in build meta data %q", str) + } + v.Build = append(v.Build, str) + } + + return v, nil +} + +// MustParse is like Parse but panics if the version cannot be parsed. +func MustParse(s string) Version { + v, err := Parse(s) + if err != nil { + panic(`semver: Parse(` + s + `): ` + err.Error()) + } + return v +} + +// PRVersion represents a PreRelease Version +type PRVersion struct { + VersionStr string + VersionNum uint64 + IsNum bool +} + +// NewPRVersion creates a new valid prerelease version +func NewPRVersion(s string) (PRVersion, error) { + if len(s) == 0 { + return PRVersion{}, errors.New("Prerelease is empty") + } + v := PRVersion{} + if containsOnly(s, numbers) { + if hasLeadingZeroes(s) { + return PRVersion{}, fmt.Errorf("Numeric PreRelease version must not contain leading zeroes %q", s) + } + num, err := strconv.ParseUint(s, 10, 64) + + // Might never be hit, but just in case + if err != nil { + return PRVersion{}, err + } + v.VersionNum = num + v.IsNum = true + } else if containsOnly(s, alphanum) { + v.VersionStr = s + v.IsNum = false + } else { + return PRVersion{}, fmt.Errorf("Invalid character(s) found in prerelease %q", s) + } + return v, nil +} + +// IsNumeric checks if prerelease-version is numeric +func (v PRVersion) IsNumeric() bool { + return v.IsNum +} + +// Compare compares two PreRelease Versions v and o: +// -1 == v is less than o +// 0 == v is equal to o +// 1 == v is greater than o +func (v PRVersion) Compare(o PRVersion) int { + if v.IsNum && !o.IsNum { + return -1 + } else if !v.IsNum && o.IsNum { + return 1 + } else if v.IsNum && o.IsNum { + if v.VersionNum == o.VersionNum { + return 0 + } else if v.VersionNum > o.VersionNum { + return 1 + } else { + return -1 + } + } else { // both are Alphas + if v.VersionStr == o.VersionStr { + return 0 + } else if v.VersionStr > o.VersionStr { + return 1 + } else { + return -1 + } + } +} + +// PreRelease version to string +func (v PRVersion) String() string { + if v.IsNum { + return strconv.FormatUint(v.VersionNum, 10) + } + return v.VersionStr +} + +func containsOnly(s string, set string) bool { + return strings.IndexFunc(s, func(r rune) bool { + return !strings.ContainsRune(set, r) + }) == -1 +} + +func hasLeadingZeroes(s string) bool { + return len(s) > 1 && s[0] == '0' +} + +// NewBuildVersion creates a new valid build version +func NewBuildVersion(s string) (string, error) { + if len(s) == 0 { + return "", errors.New("Buildversion is empty") + } + if !containsOnly(s, alphanum) { + return "", fmt.Errorf("Invalid character(s) found in build meta data %q", s) + } + return s, nil +} + +// FinalizeVersion returns the major, minor and patch number only and discards +// prerelease and build number. +func FinalizeVersion(s string) (string, error) { + v, err := Parse(s) + if err != nil { + return "", err + } + v.Pre = nil + v.Build = nil + + finalVer := v.String() + return finalVer, nil +} diff --git a/go-controller/vendor/github.com/blang/semver/v4/sort.go b/go-controller/vendor/github.com/blang/semver/v4/sort.go new file mode 100644 index 0000000000..e18f880826 --- /dev/null +++ b/go-controller/vendor/github.com/blang/semver/v4/sort.go @@ -0,0 +1,28 @@ +package semver + +import ( + "sort" +) + +// Versions represents multiple versions. +type Versions []Version + +// Len returns length of version collection +func (s Versions) Len() int { + return len(s) +} + +// Swap swaps two versions inside the collection by its indices +func (s Versions) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} + +// Less checks if version at index i is less than version at index j +func (s Versions) Less(i, j int) bool { + return s[i].LT(s[j]) +} + +// Sort sorts a slice of versions +func Sort(versions []Version) { + sort.Sort(Versions(versions)) +} diff --git a/go-controller/vendor/github.com/blang/semver/v4/sql.go b/go-controller/vendor/github.com/blang/semver/v4/sql.go new file mode 100644 index 0000000000..db958134f3 --- /dev/null +++ b/go-controller/vendor/github.com/blang/semver/v4/sql.go @@ -0,0 +1,30 @@ +package semver + +import ( + "database/sql/driver" + "fmt" +) + +// Scan implements the database/sql.Scanner interface. +func (v *Version) Scan(src interface{}) (err error) { + var str string + switch src := src.(type) { + case string: + str = src + case []byte: + str = string(src) + default: + return fmt.Errorf("version.Scan: cannot convert %T to string", src) + } + + if t, err := Parse(str); err == nil { + *v = t + } + + return +} + +// Value implements the database/sql/driver.Valuer interface. +func (v Version) Value() (driver.Value, error) { + return v.String(), nil +} diff --git a/go-controller/vendor/github.com/golang/protobuf/AUTHORS b/go-controller/vendor/github.com/golang/protobuf/AUTHORS deleted file mode 100644 index 15167cd746..0000000000 --- a/go-controller/vendor/github.com/golang/protobuf/AUTHORS +++ /dev/null @@ -1,3 +0,0 @@ -# This source code refers to The Go Authors for copyright purposes. -# The master list of authors is in the main Go distribution, -# visible at http://tip.golang.org/AUTHORS. diff --git a/go-controller/vendor/github.com/golang/protobuf/CONTRIBUTORS b/go-controller/vendor/github.com/golang/protobuf/CONTRIBUTORS deleted file mode 100644 index 1c4577e968..0000000000 --- a/go-controller/vendor/github.com/golang/protobuf/CONTRIBUTORS +++ /dev/null @@ -1,3 +0,0 @@ -# This source code was written by the Go contributors. -# The master list of contributors is in the main Go distribution, -# visible at http://tip.golang.org/CONTRIBUTORS. diff --git a/go-controller/vendor/github.com/golang/protobuf/proto/buffer.go b/go-controller/vendor/github.com/golang/protobuf/proto/buffer.go deleted file mode 100644 index e810e6fea1..0000000000 --- a/go-controller/vendor/github.com/golang/protobuf/proto/buffer.go +++ /dev/null @@ -1,324 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package proto - -import ( - "errors" - "fmt" - - "google.golang.org/protobuf/encoding/prototext" - "google.golang.org/protobuf/encoding/protowire" - "google.golang.org/protobuf/runtime/protoimpl" -) - -const ( - WireVarint = 0 - WireFixed32 = 5 - WireFixed64 = 1 - WireBytes = 2 - WireStartGroup = 3 - WireEndGroup = 4 -) - -// EncodeVarint returns the varint encoded bytes of v. -func EncodeVarint(v uint64) []byte { - return protowire.AppendVarint(nil, v) -} - -// SizeVarint returns the length of the varint encoded bytes of v. -// This is equal to len(EncodeVarint(v)). -func SizeVarint(v uint64) int { - return protowire.SizeVarint(v) -} - -// DecodeVarint parses a varint encoded integer from b, -// returning the integer value and the length of the varint. -// It returns (0, 0) if there is a parse error. -func DecodeVarint(b []byte) (uint64, int) { - v, n := protowire.ConsumeVarint(b) - if n < 0 { - return 0, 0 - } - return v, n -} - -// Buffer is a buffer for encoding and decoding the protobuf wire format. -// It may be reused between invocations to reduce memory usage. -type Buffer struct { - buf []byte - idx int - deterministic bool -} - -// NewBuffer allocates a new Buffer initialized with buf, -// where the contents of buf are considered the unread portion of the buffer. -func NewBuffer(buf []byte) *Buffer { - return &Buffer{buf: buf} -} - -// SetDeterministic specifies whether to use deterministic serialization. -// -// Deterministic serialization guarantees that for a given binary, equal -// messages will always be serialized to the same bytes. This implies: -// -// - Repeated serialization of a message will return the same bytes. -// - Different processes of the same binary (which may be executing on -// different machines) will serialize equal messages to the same bytes. -// -// Note that the deterministic serialization is NOT canonical across -// languages. It is not guaranteed to remain stable over time. It is unstable -// across different builds with schema changes due to unknown fields. -// Users who need canonical serialization (e.g., persistent storage in a -// canonical form, fingerprinting, etc.) should define their own -// canonicalization specification and implement their own serializer rather -// than relying on this API. -// -// If deterministic serialization is requested, map entries will be sorted -// by keys in lexographical order. This is an implementation detail and -// subject to change. -func (b *Buffer) SetDeterministic(deterministic bool) { - b.deterministic = deterministic -} - -// SetBuf sets buf as the internal buffer, -// where the contents of buf are considered the unread portion of the buffer. -func (b *Buffer) SetBuf(buf []byte) { - b.buf = buf - b.idx = 0 -} - -// Reset clears the internal buffer of all written and unread data. -func (b *Buffer) Reset() { - b.buf = b.buf[:0] - b.idx = 0 -} - -// Bytes returns the internal buffer. -func (b *Buffer) Bytes() []byte { - return b.buf -} - -// Unread returns the unread portion of the buffer. -func (b *Buffer) Unread() []byte { - return b.buf[b.idx:] -} - -// Marshal appends the wire-format encoding of m to the buffer. -func (b *Buffer) Marshal(m Message) error { - var err error - b.buf, err = marshalAppend(b.buf, m, b.deterministic) - return err -} - -// Unmarshal parses the wire-format message in the buffer and -// places the decoded results in m. -// It does not reset m before unmarshaling. -func (b *Buffer) Unmarshal(m Message) error { - err := UnmarshalMerge(b.Unread(), m) - b.idx = len(b.buf) - return err -} - -type unknownFields struct{ XXX_unrecognized protoimpl.UnknownFields } - -func (m *unknownFields) String() string { panic("not implemented") } -func (m *unknownFields) Reset() { panic("not implemented") } -func (m *unknownFields) ProtoMessage() { panic("not implemented") } - -// DebugPrint dumps the encoded bytes of b with a header and footer including s -// to stdout. This is only intended for debugging. -func (*Buffer) DebugPrint(s string, b []byte) { - m := MessageReflect(new(unknownFields)) - m.SetUnknown(b) - b, _ = prototext.MarshalOptions{AllowPartial: true, Indent: "\t"}.Marshal(m.Interface()) - fmt.Printf("==== %s ====\n%s==== %s ====\n", s, b, s) -} - -// EncodeVarint appends an unsigned varint encoding to the buffer. -func (b *Buffer) EncodeVarint(v uint64) error { - b.buf = protowire.AppendVarint(b.buf, v) - return nil -} - -// EncodeZigzag32 appends a 32-bit zig-zag varint encoding to the buffer. -func (b *Buffer) EncodeZigzag32(v uint64) error { - return b.EncodeVarint(uint64((uint32(v) << 1) ^ uint32((int32(v) >> 31)))) -} - -// EncodeZigzag64 appends a 64-bit zig-zag varint encoding to the buffer. -func (b *Buffer) EncodeZigzag64(v uint64) error { - return b.EncodeVarint(uint64((uint64(v) << 1) ^ uint64((int64(v) >> 63)))) -} - -// EncodeFixed32 appends a 32-bit little-endian integer to the buffer. -func (b *Buffer) EncodeFixed32(v uint64) error { - b.buf = protowire.AppendFixed32(b.buf, uint32(v)) - return nil -} - -// EncodeFixed64 appends a 64-bit little-endian integer to the buffer. -func (b *Buffer) EncodeFixed64(v uint64) error { - b.buf = protowire.AppendFixed64(b.buf, uint64(v)) - return nil -} - -// EncodeRawBytes appends a length-prefixed raw bytes to the buffer. -func (b *Buffer) EncodeRawBytes(v []byte) error { - b.buf = protowire.AppendBytes(b.buf, v) - return nil -} - -// EncodeStringBytes appends a length-prefixed raw bytes to the buffer. -// It does not validate whether v contains valid UTF-8. -func (b *Buffer) EncodeStringBytes(v string) error { - b.buf = protowire.AppendString(b.buf, v) - return nil -} - -// EncodeMessage appends a length-prefixed encoded message to the buffer. -func (b *Buffer) EncodeMessage(m Message) error { - var err error - b.buf = protowire.AppendVarint(b.buf, uint64(Size(m))) - b.buf, err = marshalAppend(b.buf, m, b.deterministic) - return err -} - -// DecodeVarint consumes an encoded unsigned varint from the buffer. -func (b *Buffer) DecodeVarint() (uint64, error) { - v, n := protowire.ConsumeVarint(b.buf[b.idx:]) - if n < 0 { - return 0, protowire.ParseError(n) - } - b.idx += n - return uint64(v), nil -} - -// DecodeZigzag32 consumes an encoded 32-bit zig-zag varint from the buffer. -func (b *Buffer) DecodeZigzag32() (uint64, error) { - v, err := b.DecodeVarint() - if err != nil { - return 0, err - } - return uint64((uint32(v) >> 1) ^ uint32((int32(v&1)<<31)>>31)), nil -} - -// DecodeZigzag64 consumes an encoded 64-bit zig-zag varint from the buffer. -func (b *Buffer) DecodeZigzag64() (uint64, error) { - v, err := b.DecodeVarint() - if err != nil { - return 0, err - } - return uint64((uint64(v) >> 1) ^ uint64((int64(v&1)<<63)>>63)), nil -} - -// DecodeFixed32 consumes a 32-bit little-endian integer from the buffer. -func (b *Buffer) DecodeFixed32() (uint64, error) { - v, n := protowire.ConsumeFixed32(b.buf[b.idx:]) - if n < 0 { - return 0, protowire.ParseError(n) - } - b.idx += n - return uint64(v), nil -} - -// DecodeFixed64 consumes a 64-bit little-endian integer from the buffer. -func (b *Buffer) DecodeFixed64() (uint64, error) { - v, n := protowire.ConsumeFixed64(b.buf[b.idx:]) - if n < 0 { - return 0, protowire.ParseError(n) - } - b.idx += n - return uint64(v), nil -} - -// DecodeRawBytes consumes a length-prefixed raw bytes from the buffer. -// If alloc is specified, it returns a copy the raw bytes -// rather than a sub-slice of the buffer. -func (b *Buffer) DecodeRawBytes(alloc bool) ([]byte, error) { - v, n := protowire.ConsumeBytes(b.buf[b.idx:]) - if n < 0 { - return nil, protowire.ParseError(n) - } - b.idx += n - if alloc { - v = append([]byte(nil), v...) - } - return v, nil -} - -// DecodeStringBytes consumes a length-prefixed raw bytes from the buffer. -// It does not validate whether the raw bytes contain valid UTF-8. -func (b *Buffer) DecodeStringBytes() (string, error) { - v, n := protowire.ConsumeString(b.buf[b.idx:]) - if n < 0 { - return "", protowire.ParseError(n) - } - b.idx += n - return v, nil -} - -// DecodeMessage consumes a length-prefixed message from the buffer. -// It does not reset m before unmarshaling. -func (b *Buffer) DecodeMessage(m Message) error { - v, err := b.DecodeRawBytes(false) - if err != nil { - return err - } - return UnmarshalMerge(v, m) -} - -// DecodeGroup consumes a message group from the buffer. -// It assumes that the start group marker has already been consumed and -// consumes all bytes until (and including the end group marker). -// It does not reset m before unmarshaling. -func (b *Buffer) DecodeGroup(m Message) error { - v, n, err := consumeGroup(b.buf[b.idx:]) - if err != nil { - return err - } - b.idx += n - return UnmarshalMerge(v, m) -} - -// consumeGroup parses b until it finds an end group marker, returning -// the raw bytes of the message (excluding the end group marker) and the -// the total length of the message (including the end group marker). -func consumeGroup(b []byte) ([]byte, int, error) { - b0 := b - depth := 1 // assume this follows a start group marker - for { - _, wtyp, tagLen := protowire.ConsumeTag(b) - if tagLen < 0 { - return nil, 0, protowire.ParseError(tagLen) - } - b = b[tagLen:] - - var valLen int - switch wtyp { - case protowire.VarintType: - _, valLen = protowire.ConsumeVarint(b) - case protowire.Fixed32Type: - _, valLen = protowire.ConsumeFixed32(b) - case protowire.Fixed64Type: - _, valLen = protowire.ConsumeFixed64(b) - case protowire.BytesType: - _, valLen = protowire.ConsumeBytes(b) - case protowire.StartGroupType: - depth++ - case protowire.EndGroupType: - depth-- - default: - return nil, 0, errors.New("proto: cannot parse reserved wire type") - } - if valLen < 0 { - return nil, 0, protowire.ParseError(valLen) - } - b = b[valLen:] - - if depth == 0 { - return b0[:len(b0)-len(b)-tagLen], len(b0) - len(b), nil - } - } -} diff --git a/go-controller/vendor/github.com/golang/protobuf/proto/defaults.go b/go-controller/vendor/github.com/golang/protobuf/proto/defaults.go deleted file mode 100644 index d399bf069c..0000000000 --- a/go-controller/vendor/github.com/golang/protobuf/proto/defaults.go +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package proto - -import ( - "google.golang.org/protobuf/reflect/protoreflect" -) - -// SetDefaults sets unpopulated scalar fields to their default values. -// Fields within a oneof are not set even if they have a default value. -// SetDefaults is recursively called upon any populated message fields. -func SetDefaults(m Message) { - if m != nil { - setDefaults(MessageReflect(m)) - } -} - -func setDefaults(m protoreflect.Message) { - fds := m.Descriptor().Fields() - for i := 0; i < fds.Len(); i++ { - fd := fds.Get(i) - if !m.Has(fd) { - if fd.HasDefault() && fd.ContainingOneof() == nil { - v := fd.Default() - if fd.Kind() == protoreflect.BytesKind { - v = protoreflect.ValueOf(append([]byte(nil), v.Bytes()...)) // copy the default bytes - } - m.Set(fd, v) - } - continue - } - } - - m.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { - switch { - // Handle singular message. - case fd.Cardinality() != protoreflect.Repeated: - if fd.Message() != nil { - setDefaults(m.Get(fd).Message()) - } - // Handle list of messages. - case fd.IsList(): - if fd.Message() != nil { - ls := m.Get(fd).List() - for i := 0; i < ls.Len(); i++ { - setDefaults(ls.Get(i).Message()) - } - } - // Handle map of messages. - case fd.IsMap(): - if fd.MapValue().Message() != nil { - ms := m.Get(fd).Map() - ms.Range(func(_ protoreflect.MapKey, v protoreflect.Value) bool { - setDefaults(v.Message()) - return true - }) - } - } - return true - }) -} diff --git a/go-controller/vendor/github.com/golang/protobuf/proto/deprecated.go b/go-controller/vendor/github.com/golang/protobuf/proto/deprecated.go deleted file mode 100644 index e8db57e097..0000000000 --- a/go-controller/vendor/github.com/golang/protobuf/proto/deprecated.go +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package proto - -import ( - "encoding/json" - "errors" - "fmt" - "strconv" - - protoV2 "google.golang.org/protobuf/proto" -) - -var ( - // Deprecated: No longer returned. - ErrNil = errors.New("proto: Marshal called with nil") - - // Deprecated: No longer returned. - ErrTooLarge = errors.New("proto: message encodes to over 2 GB") - - // Deprecated: No longer returned. - ErrInternalBadWireType = errors.New("proto: internal error: bad wiretype for oneof") -) - -// Deprecated: Do not use. -type Stats struct{ Emalloc, Dmalloc, Encode, Decode, Chit, Cmiss, Size uint64 } - -// Deprecated: Do not use. -func GetStats() Stats { return Stats{} } - -// Deprecated: Do not use. -func MarshalMessageSet(interface{}) ([]byte, error) { - return nil, errors.New("proto: not implemented") -} - -// Deprecated: Do not use. -func UnmarshalMessageSet([]byte, interface{}) error { - return errors.New("proto: not implemented") -} - -// Deprecated: Do not use. -func MarshalMessageSetJSON(interface{}) ([]byte, error) { - return nil, errors.New("proto: not implemented") -} - -// Deprecated: Do not use. -func UnmarshalMessageSetJSON([]byte, interface{}) error { - return errors.New("proto: not implemented") -} - -// Deprecated: Do not use. -func RegisterMessageSetType(Message, int32, string) {} - -// Deprecated: Do not use. -func EnumName(m map[int32]string, v int32) string { - s, ok := m[v] - if ok { - return s - } - return strconv.Itoa(int(v)) -} - -// Deprecated: Do not use. -func UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string) (int32, error) { - if data[0] == '"' { - // New style: enums are strings. - var repr string - if err := json.Unmarshal(data, &repr); err != nil { - return -1, err - } - val, ok := m[repr] - if !ok { - return 0, fmt.Errorf("unrecognized enum %s value %q", enumName, repr) - } - return val, nil - } - // Old style: enums are ints. - var val int32 - if err := json.Unmarshal(data, &val); err != nil { - return 0, fmt.Errorf("cannot unmarshal %#q into enum %s", data, enumName) - } - return val, nil -} - -// Deprecated: Do not use; this type existed for intenal-use only. -type InternalMessageInfo struct{} - -// Deprecated: Do not use; this method existed for intenal-use only. -func (*InternalMessageInfo) DiscardUnknown(m Message) { - DiscardUnknown(m) -} - -// Deprecated: Do not use; this method existed for intenal-use only. -func (*InternalMessageInfo) Marshal(b []byte, m Message, deterministic bool) ([]byte, error) { - return protoV2.MarshalOptions{Deterministic: deterministic}.MarshalAppend(b, MessageV2(m)) -} - -// Deprecated: Do not use; this method existed for intenal-use only. -func (*InternalMessageInfo) Merge(dst, src Message) { - protoV2.Merge(MessageV2(dst), MessageV2(src)) -} - -// Deprecated: Do not use; this method existed for intenal-use only. -func (*InternalMessageInfo) Size(m Message) int { - return protoV2.Size(MessageV2(m)) -} - -// Deprecated: Do not use; this method existed for intenal-use only. -func (*InternalMessageInfo) Unmarshal(m Message, b []byte) error { - return protoV2.UnmarshalOptions{Merge: true}.Unmarshal(b, MessageV2(m)) -} diff --git a/go-controller/vendor/github.com/golang/protobuf/proto/discard.go b/go-controller/vendor/github.com/golang/protobuf/proto/discard.go deleted file mode 100644 index 2187e877fa..0000000000 --- a/go-controller/vendor/github.com/golang/protobuf/proto/discard.go +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package proto - -import ( - "google.golang.org/protobuf/reflect/protoreflect" -) - -// DiscardUnknown recursively discards all unknown fields from this message -// and all embedded messages. -// -// When unmarshaling a message with unrecognized fields, the tags and values -// of such fields are preserved in the Message. This allows a later call to -// marshal to be able to produce a message that continues to have those -// unrecognized fields. To avoid this, DiscardUnknown is used to -// explicitly clear the unknown fields after unmarshaling. -func DiscardUnknown(m Message) { - if m != nil { - discardUnknown(MessageReflect(m)) - } -} - -func discardUnknown(m protoreflect.Message) { - m.Range(func(fd protoreflect.FieldDescriptor, val protoreflect.Value) bool { - switch { - // Handle singular message. - case fd.Cardinality() != protoreflect.Repeated: - if fd.Message() != nil { - discardUnknown(m.Get(fd).Message()) - } - // Handle list of messages. - case fd.IsList(): - if fd.Message() != nil { - ls := m.Get(fd).List() - for i := 0; i < ls.Len(); i++ { - discardUnknown(ls.Get(i).Message()) - } - } - // Handle map of messages. - case fd.IsMap(): - if fd.MapValue().Message() != nil { - ms := m.Get(fd).Map() - ms.Range(func(_ protoreflect.MapKey, v protoreflect.Value) bool { - discardUnknown(v.Message()) - return true - }) - } - } - return true - }) - - // Discard unknown fields. - if len(m.GetUnknown()) > 0 { - m.SetUnknown(nil) - } -} diff --git a/go-controller/vendor/github.com/golang/protobuf/proto/extensions.go b/go-controller/vendor/github.com/golang/protobuf/proto/extensions.go deleted file mode 100644 index 42fc120c97..0000000000 --- a/go-controller/vendor/github.com/golang/protobuf/proto/extensions.go +++ /dev/null @@ -1,356 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package proto - -import ( - "errors" - "fmt" - "reflect" - - "google.golang.org/protobuf/encoding/protowire" - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/reflect/protoregistry" - "google.golang.org/protobuf/runtime/protoiface" - "google.golang.org/protobuf/runtime/protoimpl" -) - -type ( - // ExtensionDesc represents an extension descriptor and - // is used to interact with an extension field in a message. - // - // Variables of this type are generated in code by protoc-gen-go. - ExtensionDesc = protoimpl.ExtensionInfo - - // ExtensionRange represents a range of message extensions. - // Used in code generated by protoc-gen-go. - ExtensionRange = protoiface.ExtensionRangeV1 - - // Deprecated: Do not use; this is an internal type. - Extension = protoimpl.ExtensionFieldV1 - - // Deprecated: Do not use; this is an internal type. - XXX_InternalExtensions = protoimpl.ExtensionFields -) - -// ErrMissingExtension reports whether the extension was not present. -var ErrMissingExtension = errors.New("proto: missing extension") - -var errNotExtendable = errors.New("proto: not an extendable proto.Message") - -// HasExtension reports whether the extension field is present in m -// either as an explicitly populated field or as an unknown field. -func HasExtension(m Message, xt *ExtensionDesc) (has bool) { - mr := MessageReflect(m) - if mr == nil || !mr.IsValid() { - return false - } - - // Check whether any populated known field matches the field number. - xtd := xt.TypeDescriptor() - if isValidExtension(mr.Descriptor(), xtd) { - has = mr.Has(xtd) - } else { - mr.Range(func(fd protoreflect.FieldDescriptor, _ protoreflect.Value) bool { - has = int32(fd.Number()) == xt.Field - return !has - }) - } - - // Check whether any unknown field matches the field number. - for b := mr.GetUnknown(); !has && len(b) > 0; { - num, _, n := protowire.ConsumeField(b) - has = int32(num) == xt.Field - b = b[n:] - } - return has -} - -// ClearExtension removes the extension field from m -// either as an explicitly populated field or as an unknown field. -func ClearExtension(m Message, xt *ExtensionDesc) { - mr := MessageReflect(m) - if mr == nil || !mr.IsValid() { - return - } - - xtd := xt.TypeDescriptor() - if isValidExtension(mr.Descriptor(), xtd) { - mr.Clear(xtd) - } else { - mr.Range(func(fd protoreflect.FieldDescriptor, _ protoreflect.Value) bool { - if int32(fd.Number()) == xt.Field { - mr.Clear(fd) - return false - } - return true - }) - } - clearUnknown(mr, fieldNum(xt.Field)) -} - -// ClearAllExtensions clears all extensions from m. -// This includes populated fields and unknown fields in the extension range. -func ClearAllExtensions(m Message) { - mr := MessageReflect(m) - if mr == nil || !mr.IsValid() { - return - } - - mr.Range(func(fd protoreflect.FieldDescriptor, _ protoreflect.Value) bool { - if fd.IsExtension() { - mr.Clear(fd) - } - return true - }) - clearUnknown(mr, mr.Descriptor().ExtensionRanges()) -} - -// GetExtension retrieves a proto2 extended field from m. -// -// If the descriptor is type complete (i.e., ExtensionDesc.ExtensionType is non-nil), -// then GetExtension parses the encoded field and returns a Go value of the specified type. -// If the field is not present, then the default value is returned (if one is specified), -// otherwise ErrMissingExtension is reported. -// -// If the descriptor is type incomplete (i.e., ExtensionDesc.ExtensionType is nil), -// then GetExtension returns the raw encoded bytes for the extension field. -func GetExtension(m Message, xt *ExtensionDesc) (interface{}, error) { - mr := MessageReflect(m) - if mr == nil || !mr.IsValid() || mr.Descriptor().ExtensionRanges().Len() == 0 { - return nil, errNotExtendable - } - - // Retrieve the unknown fields for this extension field. - var bo protoreflect.RawFields - for bi := mr.GetUnknown(); len(bi) > 0; { - num, _, n := protowire.ConsumeField(bi) - if int32(num) == xt.Field { - bo = append(bo, bi[:n]...) - } - bi = bi[n:] - } - - // For type incomplete descriptors, only retrieve the unknown fields. - if xt.ExtensionType == nil { - return []byte(bo), nil - } - - // If the extension field only exists as unknown fields, unmarshal it. - // This is rarely done since proto.Unmarshal eagerly unmarshals extensions. - xtd := xt.TypeDescriptor() - if !isValidExtension(mr.Descriptor(), xtd) { - return nil, fmt.Errorf("proto: bad extended type; %T does not extend %T", xt.ExtendedType, m) - } - if !mr.Has(xtd) && len(bo) > 0 { - m2 := mr.New() - if err := (proto.UnmarshalOptions{ - Resolver: extensionResolver{xt}, - }.Unmarshal(bo, m2.Interface())); err != nil { - return nil, err - } - if m2.Has(xtd) { - mr.Set(xtd, m2.Get(xtd)) - clearUnknown(mr, fieldNum(xt.Field)) - } - } - - // Check whether the message has the extension field set or a default. - var pv protoreflect.Value - switch { - case mr.Has(xtd): - pv = mr.Get(xtd) - case xtd.HasDefault(): - pv = xtd.Default() - default: - return nil, ErrMissingExtension - } - - v := xt.InterfaceOf(pv) - rv := reflect.ValueOf(v) - if isScalarKind(rv.Kind()) { - rv2 := reflect.New(rv.Type()) - rv2.Elem().Set(rv) - v = rv2.Interface() - } - return v, nil -} - -// extensionResolver is a custom extension resolver that stores a single -// extension type that takes precedence over the global registry. -type extensionResolver struct{ xt protoreflect.ExtensionType } - -func (r extensionResolver) FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error) { - if xtd := r.xt.TypeDescriptor(); xtd.FullName() == field { - return r.xt, nil - } - return protoregistry.GlobalTypes.FindExtensionByName(field) -} - -func (r extensionResolver) FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error) { - if xtd := r.xt.TypeDescriptor(); xtd.ContainingMessage().FullName() == message && xtd.Number() == field { - return r.xt, nil - } - return protoregistry.GlobalTypes.FindExtensionByNumber(message, field) -} - -// GetExtensions returns a list of the extensions values present in m, -// corresponding with the provided list of extension descriptors, xts. -// If an extension is missing in m, the corresponding value is nil. -func GetExtensions(m Message, xts []*ExtensionDesc) ([]interface{}, error) { - mr := MessageReflect(m) - if mr == nil || !mr.IsValid() { - return nil, errNotExtendable - } - - vs := make([]interface{}, len(xts)) - for i, xt := range xts { - v, err := GetExtension(m, xt) - if err != nil { - if err == ErrMissingExtension { - continue - } - return vs, err - } - vs[i] = v - } - return vs, nil -} - -// SetExtension sets an extension field in m to the provided value. -func SetExtension(m Message, xt *ExtensionDesc, v interface{}) error { - mr := MessageReflect(m) - if mr == nil || !mr.IsValid() || mr.Descriptor().ExtensionRanges().Len() == 0 { - return errNotExtendable - } - - rv := reflect.ValueOf(v) - if reflect.TypeOf(v) != reflect.TypeOf(xt.ExtensionType) { - return fmt.Errorf("proto: bad extension value type. got: %T, want: %T", v, xt.ExtensionType) - } - if rv.Kind() == reflect.Ptr { - if rv.IsNil() { - return fmt.Errorf("proto: SetExtension called with nil value of type %T", v) - } - if isScalarKind(rv.Elem().Kind()) { - v = rv.Elem().Interface() - } - } - - xtd := xt.TypeDescriptor() - if !isValidExtension(mr.Descriptor(), xtd) { - return fmt.Errorf("proto: bad extended type; %T does not extend %T", xt.ExtendedType, m) - } - mr.Set(xtd, xt.ValueOf(v)) - clearUnknown(mr, fieldNum(xt.Field)) - return nil -} - -// SetRawExtension inserts b into the unknown fields of m. -// -// Deprecated: Use Message.ProtoReflect.SetUnknown instead. -func SetRawExtension(m Message, fnum int32, b []byte) { - mr := MessageReflect(m) - if mr == nil || !mr.IsValid() { - return - } - - // Verify that the raw field is valid. - for b0 := b; len(b0) > 0; { - num, _, n := protowire.ConsumeField(b0) - if int32(num) != fnum { - panic(fmt.Sprintf("mismatching field number: got %d, want %d", num, fnum)) - } - b0 = b0[n:] - } - - ClearExtension(m, &ExtensionDesc{Field: fnum}) - mr.SetUnknown(append(mr.GetUnknown(), b...)) -} - -// ExtensionDescs returns a list of extension descriptors found in m, -// containing descriptors for both populated extension fields in m and -// also unknown fields of m that are in the extension range. -// For the later case, an type incomplete descriptor is provided where only -// the ExtensionDesc.Field field is populated. -// The order of the extension descriptors is undefined. -func ExtensionDescs(m Message) ([]*ExtensionDesc, error) { - mr := MessageReflect(m) - if mr == nil || !mr.IsValid() || mr.Descriptor().ExtensionRanges().Len() == 0 { - return nil, errNotExtendable - } - - // Collect a set of known extension descriptors. - extDescs := make(map[protoreflect.FieldNumber]*ExtensionDesc) - mr.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { - if fd.IsExtension() { - xt := fd.(protoreflect.ExtensionTypeDescriptor) - if xd, ok := xt.Type().(*ExtensionDesc); ok { - extDescs[fd.Number()] = xd - } - } - return true - }) - - // Collect a set of unknown extension descriptors. - extRanges := mr.Descriptor().ExtensionRanges() - for b := mr.GetUnknown(); len(b) > 0; { - num, _, n := protowire.ConsumeField(b) - if extRanges.Has(num) && extDescs[num] == nil { - extDescs[num] = nil - } - b = b[n:] - } - - // Transpose the set of descriptors into a list. - var xts []*ExtensionDesc - for num, xt := range extDescs { - if xt == nil { - xt = &ExtensionDesc{Field: int32(num)} - } - xts = append(xts, xt) - } - return xts, nil -} - -// isValidExtension reports whether xtd is a valid extension descriptor for md. -func isValidExtension(md protoreflect.MessageDescriptor, xtd protoreflect.ExtensionTypeDescriptor) bool { - return xtd.ContainingMessage() == md && md.ExtensionRanges().Has(xtd.Number()) -} - -// isScalarKind reports whether k is a protobuf scalar kind (except bytes). -// This function exists for historical reasons since the representation of -// scalars differs between v1 and v2, where v1 uses *T and v2 uses T. -func isScalarKind(k reflect.Kind) bool { - switch k { - case reflect.Bool, reflect.Int32, reflect.Int64, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64, reflect.String: - return true - default: - return false - } -} - -// clearUnknown removes unknown fields from m where remover.Has reports true. -func clearUnknown(m protoreflect.Message, remover interface { - Has(protoreflect.FieldNumber) bool -}) { - var bo protoreflect.RawFields - for bi := m.GetUnknown(); len(bi) > 0; { - num, _, n := protowire.ConsumeField(bi) - if !remover.Has(num) { - bo = append(bo, bi[:n]...) - } - bi = bi[n:] - } - if bi := m.GetUnknown(); len(bi) != len(bo) { - m.SetUnknown(bo) - } -} - -type fieldNum protoreflect.FieldNumber - -func (n1 fieldNum) Has(n2 protoreflect.FieldNumber) bool { - return protoreflect.FieldNumber(n1) == n2 -} diff --git a/go-controller/vendor/github.com/golang/protobuf/proto/properties.go b/go-controller/vendor/github.com/golang/protobuf/proto/properties.go deleted file mode 100644 index dcdc2202fa..0000000000 --- a/go-controller/vendor/github.com/golang/protobuf/proto/properties.go +++ /dev/null @@ -1,306 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package proto - -import ( - "fmt" - "reflect" - "strconv" - "strings" - "sync" - - "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/runtime/protoimpl" -) - -// StructProperties represents protocol buffer type information for a -// generated protobuf message in the open-struct API. -// -// Deprecated: Do not use. -type StructProperties struct { - // Prop are the properties for each field. - // - // Fields belonging to a oneof are stored in OneofTypes instead, with a - // single Properties representing the parent oneof held here. - // - // The order of Prop matches the order of fields in the Go struct. - // Struct fields that are not related to protobufs have a "XXX_" prefix - // in the Properties.Name and must be ignored by the user. - Prop []*Properties - - // OneofTypes contains information about the oneof fields in this message. - // It is keyed by the protobuf field name. - OneofTypes map[string]*OneofProperties -} - -// Properties represents the type information for a protobuf message field. -// -// Deprecated: Do not use. -type Properties struct { - // Name is a placeholder name with little meaningful semantic value. - // If the name has an "XXX_" prefix, the entire Properties must be ignored. - Name string - // OrigName is the protobuf field name or oneof name. - OrigName string - // JSONName is the JSON name for the protobuf field. - JSONName string - // Enum is a placeholder name for enums. - // For historical reasons, this is neither the Go name for the enum, - // nor the protobuf name for the enum. - Enum string // Deprecated: Do not use. - // Weak contains the full name of the weakly referenced message. - Weak string - // Wire is a string representation of the wire type. - Wire string - // WireType is the protobuf wire type for the field. - WireType int - // Tag is the protobuf field number. - Tag int - // Required reports whether this is a required field. - Required bool - // Optional reports whether this is a optional field. - Optional bool - // Repeated reports whether this is a repeated field. - Repeated bool - // Packed reports whether this is a packed repeated field of scalars. - Packed bool - // Proto3 reports whether this field operates under the proto3 syntax. - Proto3 bool - // Oneof reports whether this field belongs within a oneof. - Oneof bool - - // Default is the default value in string form. - Default string - // HasDefault reports whether the field has a default value. - HasDefault bool - - // MapKeyProp is the properties for the key field for a map field. - MapKeyProp *Properties - // MapValProp is the properties for the value field for a map field. - MapValProp *Properties -} - -// OneofProperties represents the type information for a protobuf oneof. -// -// Deprecated: Do not use. -type OneofProperties struct { - // Type is a pointer to the generated wrapper type for the field value. - // This is nil for messages that are not in the open-struct API. - Type reflect.Type - // Field is the index into StructProperties.Prop for the containing oneof. - Field int - // Prop is the properties for the field. - Prop *Properties -} - -// String formats the properties in the protobuf struct field tag style. -func (p *Properties) String() string { - s := p.Wire - s += "," + strconv.Itoa(p.Tag) - if p.Required { - s += ",req" - } - if p.Optional { - s += ",opt" - } - if p.Repeated { - s += ",rep" - } - if p.Packed { - s += ",packed" - } - s += ",name=" + p.OrigName - if p.JSONName != "" { - s += ",json=" + p.JSONName - } - if len(p.Enum) > 0 { - s += ",enum=" + p.Enum - } - if len(p.Weak) > 0 { - s += ",weak=" + p.Weak - } - if p.Proto3 { - s += ",proto3" - } - if p.Oneof { - s += ",oneof" - } - if p.HasDefault { - s += ",def=" + p.Default - } - return s -} - -// Parse populates p by parsing a string in the protobuf struct field tag style. -func (p *Properties) Parse(tag string) { - // For example: "bytes,49,opt,name=foo,def=hello!" - for len(tag) > 0 { - i := strings.IndexByte(tag, ',') - if i < 0 { - i = len(tag) - } - switch s := tag[:i]; { - case strings.HasPrefix(s, "name="): - p.OrigName = s[len("name="):] - case strings.HasPrefix(s, "json="): - p.JSONName = s[len("json="):] - case strings.HasPrefix(s, "enum="): - p.Enum = s[len("enum="):] - case strings.HasPrefix(s, "weak="): - p.Weak = s[len("weak="):] - case strings.Trim(s, "0123456789") == "": - n, _ := strconv.ParseUint(s, 10, 32) - p.Tag = int(n) - case s == "opt": - p.Optional = true - case s == "req": - p.Required = true - case s == "rep": - p.Repeated = true - case s == "varint" || s == "zigzag32" || s == "zigzag64": - p.Wire = s - p.WireType = WireVarint - case s == "fixed32": - p.Wire = s - p.WireType = WireFixed32 - case s == "fixed64": - p.Wire = s - p.WireType = WireFixed64 - case s == "bytes": - p.Wire = s - p.WireType = WireBytes - case s == "group": - p.Wire = s - p.WireType = WireStartGroup - case s == "packed": - p.Packed = true - case s == "proto3": - p.Proto3 = true - case s == "oneof": - p.Oneof = true - case strings.HasPrefix(s, "def="): - // The default tag is special in that everything afterwards is the - // default regardless of the presence of commas. - p.HasDefault = true - p.Default, i = tag[len("def="):], len(tag) - } - tag = strings.TrimPrefix(tag[i:], ",") - } -} - -// Init populates the properties from a protocol buffer struct tag. -// -// Deprecated: Do not use. -func (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) { - p.Name = name - p.OrigName = name - if tag == "" { - return - } - p.Parse(tag) - - if typ != nil && typ.Kind() == reflect.Map { - p.MapKeyProp = new(Properties) - p.MapKeyProp.Init(nil, "Key", f.Tag.Get("protobuf_key"), nil) - p.MapValProp = new(Properties) - p.MapValProp.Init(nil, "Value", f.Tag.Get("protobuf_val"), nil) - } -} - -var propertiesCache sync.Map // map[reflect.Type]*StructProperties - -// GetProperties returns the list of properties for the type represented by t, -// which must be a generated protocol buffer message in the open-struct API, -// where protobuf message fields are represented by exported Go struct fields. -// -// Deprecated: Use protobuf reflection instead. -func GetProperties(t reflect.Type) *StructProperties { - if p, ok := propertiesCache.Load(t); ok { - return p.(*StructProperties) - } - p, _ := propertiesCache.LoadOrStore(t, newProperties(t)) - return p.(*StructProperties) -} - -func newProperties(t reflect.Type) *StructProperties { - if t.Kind() != reflect.Struct { - panic(fmt.Sprintf("%v is not a generated message in the open-struct API", t)) - } - - var hasOneof bool - prop := new(StructProperties) - - // Construct a list of properties for each field in the struct. - for i := 0; i < t.NumField(); i++ { - p := new(Properties) - f := t.Field(i) - tagField := f.Tag.Get("protobuf") - p.Init(f.Type, f.Name, tagField, &f) - - tagOneof := f.Tag.Get("protobuf_oneof") - if tagOneof != "" { - hasOneof = true - p.OrigName = tagOneof - } - - // Rename unrelated struct fields with the "XXX_" prefix since so much - // user code simply checks for this to exclude special fields. - if tagField == "" && tagOneof == "" && !strings.HasPrefix(p.Name, "XXX_") { - p.Name = "XXX_" + p.Name - p.OrigName = "XXX_" + p.OrigName - } else if p.Weak != "" { - p.Name = p.OrigName // avoid possible "XXX_" prefix on weak field - } - - prop.Prop = append(prop.Prop, p) - } - - // Construct a mapping of oneof field names to properties. - if hasOneof { - var oneofWrappers []interface{} - if fn, ok := reflect.PtrTo(t).MethodByName("XXX_OneofFuncs"); ok { - oneofWrappers = fn.Func.Call([]reflect.Value{reflect.Zero(fn.Type.In(0))})[3].Interface().([]interface{}) - } - if fn, ok := reflect.PtrTo(t).MethodByName("XXX_OneofWrappers"); ok { - oneofWrappers = fn.Func.Call([]reflect.Value{reflect.Zero(fn.Type.In(0))})[0].Interface().([]interface{}) - } - if m, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(protoreflect.ProtoMessage); ok { - if m, ok := m.ProtoReflect().(interface{ ProtoMessageInfo() *protoimpl.MessageInfo }); ok { - oneofWrappers = m.ProtoMessageInfo().OneofWrappers - } - } - - prop.OneofTypes = make(map[string]*OneofProperties) - for _, wrapper := range oneofWrappers { - p := &OneofProperties{ - Type: reflect.ValueOf(wrapper).Type(), // *T - Prop: new(Properties), - } - f := p.Type.Elem().Field(0) - p.Prop.Name = f.Name - p.Prop.Parse(f.Tag.Get("protobuf")) - - // Determine the struct field that contains this oneof. - // Each wrapper is assignable to exactly one parent field. - var foundOneof bool - for i := 0; i < t.NumField() && !foundOneof; i++ { - if p.Type.AssignableTo(t.Field(i).Type) { - p.Field = i - foundOneof = true - } - } - if !foundOneof { - panic(fmt.Sprintf("%v is not a generated message in the open-struct API", t)) - } - prop.OneofTypes[p.Prop.OrigName] = p - } - } - - return prop -} - -func (sp *StructProperties) Len() int { return len(sp.Prop) } -func (sp *StructProperties) Less(i, j int) bool { return false } -func (sp *StructProperties) Swap(i, j int) { return } diff --git a/go-controller/vendor/github.com/golang/protobuf/proto/proto.go b/go-controller/vendor/github.com/golang/protobuf/proto/proto.go deleted file mode 100644 index 5aee89c323..0000000000 --- a/go-controller/vendor/github.com/golang/protobuf/proto/proto.go +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package proto provides functionality for handling protocol buffer messages. -// In particular, it provides marshaling and unmarshaling between a protobuf -// message and the binary wire format. -// -// See https://developers.google.com/protocol-buffers/docs/gotutorial for -// more information. -// -// Deprecated: Use the "google.golang.org/protobuf/proto" package instead. -package proto - -import ( - protoV2 "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/runtime/protoiface" - "google.golang.org/protobuf/runtime/protoimpl" -) - -const ( - ProtoPackageIsVersion1 = true - ProtoPackageIsVersion2 = true - ProtoPackageIsVersion3 = true - ProtoPackageIsVersion4 = true -) - -// GeneratedEnum is any enum type generated by protoc-gen-go -// which is a named int32 kind. -// This type exists for documentation purposes. -type GeneratedEnum interface{} - -// GeneratedMessage is any message type generated by protoc-gen-go -// which is a pointer to a named struct kind. -// This type exists for documentation purposes. -type GeneratedMessage interface{} - -// Message is a protocol buffer message. -// -// This is the v1 version of the message interface and is marginally better -// than an empty interface as it lacks any method to programatically interact -// with the contents of the message. -// -// A v2 message is declared in "google.golang.org/protobuf/proto".Message and -// exposes protobuf reflection as a first-class feature of the interface. -// -// To convert a v1 message to a v2 message, use the MessageV2 function. -// To convert a v2 message to a v1 message, use the MessageV1 function. -type Message = protoiface.MessageV1 - -// MessageV1 converts either a v1 or v2 message to a v1 message. -// It returns nil if m is nil. -func MessageV1(m GeneratedMessage) protoiface.MessageV1 { - return protoimpl.X.ProtoMessageV1Of(m) -} - -// MessageV2 converts either a v1 or v2 message to a v2 message. -// It returns nil if m is nil. -func MessageV2(m GeneratedMessage) protoV2.Message { - return protoimpl.X.ProtoMessageV2Of(m) -} - -// MessageReflect returns a reflective view for a message. -// It returns nil if m is nil. -func MessageReflect(m Message) protoreflect.Message { - return protoimpl.X.MessageOf(m) -} - -// Marshaler is implemented by messages that can marshal themselves. -// This interface is used by the following functions: Size, Marshal, -// Buffer.Marshal, and Buffer.EncodeMessage. -// -// Deprecated: Do not implement. -type Marshaler interface { - // Marshal formats the encoded bytes of the message. - // It should be deterministic and emit valid protobuf wire data. - // The caller takes ownership of the returned buffer. - Marshal() ([]byte, error) -} - -// Unmarshaler is implemented by messages that can unmarshal themselves. -// This interface is used by the following functions: Unmarshal, UnmarshalMerge, -// Buffer.Unmarshal, Buffer.DecodeMessage, and Buffer.DecodeGroup. -// -// Deprecated: Do not implement. -type Unmarshaler interface { - // Unmarshal parses the encoded bytes of the protobuf wire input. - // The provided buffer is only valid for during method call. - // It should not reset the receiver message. - Unmarshal([]byte) error -} - -// Merger is implemented by messages that can merge themselves. -// This interface is used by the following functions: Clone and Merge. -// -// Deprecated: Do not implement. -type Merger interface { - // Merge merges the contents of src into the receiver message. - // It clones all data structures in src such that it aliases no mutable - // memory referenced by src. - Merge(src Message) -} - -// RequiredNotSetError is an error type returned when -// marshaling or unmarshaling a message with missing required fields. -type RequiredNotSetError struct { - err error -} - -func (e *RequiredNotSetError) Error() string { - if e.err != nil { - return e.err.Error() - } - return "proto: required field not set" -} -func (e *RequiredNotSetError) RequiredNotSet() bool { - return true -} - -func checkRequiredNotSet(m protoV2.Message) error { - if err := protoV2.CheckInitialized(m); err != nil { - return &RequiredNotSetError{err: err} - } - return nil -} - -// Clone returns a deep copy of src. -func Clone(src Message) Message { - return MessageV1(protoV2.Clone(MessageV2(src))) -} - -// Merge merges src into dst, which must be messages of the same type. -// -// Populated scalar fields in src are copied to dst, while populated -// singular messages in src are merged into dst by recursively calling Merge. -// The elements of every list field in src is appended to the corresponded -// list fields in dst. The entries of every map field in src is copied into -// the corresponding map field in dst, possibly replacing existing entries. -// The unknown fields of src are appended to the unknown fields of dst. -func Merge(dst, src Message) { - protoV2.Merge(MessageV2(dst), MessageV2(src)) -} - -// Equal reports whether two messages are equal. -// If two messages marshal to the same bytes under deterministic serialization, -// then Equal is guaranteed to report true. -// -// Two messages are equal if they are the same protobuf message type, -// have the same set of populated known and extension field values, -// and the same set of unknown fields values. -// -// Scalar values are compared with the equivalent of the == operator in Go, -// except bytes values which are compared using bytes.Equal and -// floating point values which specially treat NaNs as equal. -// Message values are compared by recursively calling Equal. -// Lists are equal if each element value is also equal. -// Maps are equal if they have the same set of keys, where the pair of values -// for each key is also equal. -func Equal(x, y Message) bool { - return protoV2.Equal(MessageV2(x), MessageV2(y)) -} - -func isMessageSet(md protoreflect.MessageDescriptor) bool { - ms, ok := md.(interface{ IsMessageSet() bool }) - return ok && ms.IsMessageSet() -} diff --git a/go-controller/vendor/github.com/golang/protobuf/proto/registry.go b/go-controller/vendor/github.com/golang/protobuf/proto/registry.go deleted file mode 100644 index 066b4323b4..0000000000 --- a/go-controller/vendor/github.com/golang/protobuf/proto/registry.go +++ /dev/null @@ -1,317 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package proto - -import ( - "bytes" - "compress/gzip" - "fmt" - "io/ioutil" - "reflect" - "strings" - "sync" - - "google.golang.org/protobuf/reflect/protodesc" - "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/reflect/protoregistry" - "google.golang.org/protobuf/runtime/protoimpl" -) - -// filePath is the path to the proto source file. -type filePath = string // e.g., "google/protobuf/descriptor.proto" - -// fileDescGZIP is the compressed contents of the encoded FileDescriptorProto. -type fileDescGZIP = []byte - -var fileCache sync.Map // map[filePath]fileDescGZIP - -// RegisterFile is called from generated code to register the compressed -// FileDescriptorProto with the file path for a proto source file. -// -// Deprecated: Use protoregistry.GlobalFiles.RegisterFile instead. -func RegisterFile(s filePath, d fileDescGZIP) { - // Decompress the descriptor. - zr, err := gzip.NewReader(bytes.NewReader(d)) - if err != nil { - panic(fmt.Sprintf("proto: invalid compressed file descriptor: %v", err)) - } - b, err := ioutil.ReadAll(zr) - if err != nil { - panic(fmt.Sprintf("proto: invalid compressed file descriptor: %v", err)) - } - - // Construct a protoreflect.FileDescriptor from the raw descriptor. - // Note that DescBuilder.Build automatically registers the constructed - // file descriptor with the v2 registry. - protoimpl.DescBuilder{RawDescriptor: b}.Build() - - // Locally cache the raw descriptor form for the file. - fileCache.Store(s, d) -} - -// FileDescriptor returns the compressed FileDescriptorProto given the file path -// for a proto source file. It returns nil if not found. -// -// Deprecated: Use protoregistry.GlobalFiles.FindFileByPath instead. -func FileDescriptor(s filePath) fileDescGZIP { - if v, ok := fileCache.Load(s); ok { - return v.(fileDescGZIP) - } - - // Find the descriptor in the v2 registry. - var b []byte - if fd, _ := protoregistry.GlobalFiles.FindFileByPath(s); fd != nil { - b, _ = Marshal(protodesc.ToFileDescriptorProto(fd)) - } - - // Locally cache the raw descriptor form for the file. - if len(b) > 0 { - v, _ := fileCache.LoadOrStore(s, protoimpl.X.CompressGZIP(b)) - return v.(fileDescGZIP) - } - return nil -} - -// enumName is the name of an enum. For historical reasons, the enum name is -// neither the full Go name nor the full protobuf name of the enum. -// The name is the dot-separated combination of just the proto package that the -// enum is declared within followed by the Go type name of the generated enum. -type enumName = string // e.g., "my.proto.package.GoMessage_GoEnum" - -// enumsByName maps enum values by name to their numeric counterpart. -type enumsByName = map[string]int32 - -// enumsByNumber maps enum values by number to their name counterpart. -type enumsByNumber = map[int32]string - -var enumCache sync.Map // map[enumName]enumsByName -var numFilesCache sync.Map // map[protoreflect.FullName]int - -// RegisterEnum is called from the generated code to register the mapping of -// enum value names to enum numbers for the enum identified by s. -// -// Deprecated: Use protoregistry.GlobalTypes.RegisterEnum instead. -func RegisterEnum(s enumName, _ enumsByNumber, m enumsByName) { - if _, ok := enumCache.Load(s); ok { - panic("proto: duplicate enum registered: " + s) - } - enumCache.Store(s, m) - - // This does not forward registration to the v2 registry since this API - // lacks sufficient information to construct a complete v2 enum descriptor. -} - -// EnumValueMap returns the mapping from enum value names to enum numbers for -// the enum of the given name. It returns nil if not found. -// -// Deprecated: Use protoregistry.GlobalTypes.FindEnumByName instead. -func EnumValueMap(s enumName) enumsByName { - if v, ok := enumCache.Load(s); ok { - return v.(enumsByName) - } - - // Check whether the cache is stale. If the number of files in the current - // package differs, then it means that some enums may have been recently - // registered upstream that we do not know about. - var protoPkg protoreflect.FullName - if i := strings.LastIndexByte(s, '.'); i >= 0 { - protoPkg = protoreflect.FullName(s[:i]) - } - v, _ := numFilesCache.Load(protoPkg) - numFiles, _ := v.(int) - if protoregistry.GlobalFiles.NumFilesByPackage(protoPkg) == numFiles { - return nil // cache is up-to-date; was not found earlier - } - - // Update the enum cache for all enums declared in the given proto package. - numFiles = 0 - protoregistry.GlobalFiles.RangeFilesByPackage(protoPkg, func(fd protoreflect.FileDescriptor) bool { - walkEnums(fd, func(ed protoreflect.EnumDescriptor) { - name := protoimpl.X.LegacyEnumName(ed) - if _, ok := enumCache.Load(name); !ok { - m := make(enumsByName) - evs := ed.Values() - for i := evs.Len() - 1; i >= 0; i-- { - ev := evs.Get(i) - m[string(ev.Name())] = int32(ev.Number()) - } - enumCache.LoadOrStore(name, m) - } - }) - numFiles++ - return true - }) - numFilesCache.Store(protoPkg, numFiles) - - // Check cache again for enum map. - if v, ok := enumCache.Load(s); ok { - return v.(enumsByName) - } - return nil -} - -// walkEnums recursively walks all enums declared in d. -func walkEnums(d interface { - Enums() protoreflect.EnumDescriptors - Messages() protoreflect.MessageDescriptors -}, f func(protoreflect.EnumDescriptor)) { - eds := d.Enums() - for i := eds.Len() - 1; i >= 0; i-- { - f(eds.Get(i)) - } - mds := d.Messages() - for i := mds.Len() - 1; i >= 0; i-- { - walkEnums(mds.Get(i), f) - } -} - -// messageName is the full name of protobuf message. -type messageName = string - -var messageTypeCache sync.Map // map[messageName]reflect.Type - -// RegisterType is called from generated code to register the message Go type -// for a message of the given name. -// -// Deprecated: Use protoregistry.GlobalTypes.RegisterMessage instead. -func RegisterType(m Message, s messageName) { - mt := protoimpl.X.LegacyMessageTypeOf(m, protoreflect.FullName(s)) - if err := protoregistry.GlobalTypes.RegisterMessage(mt); err != nil { - panic(err) - } - messageTypeCache.Store(s, reflect.TypeOf(m)) -} - -// RegisterMapType is called from generated code to register the Go map type -// for a protobuf message representing a map entry. -// -// Deprecated: Do not use. -func RegisterMapType(m interface{}, s messageName) { - t := reflect.TypeOf(m) - if t.Kind() != reflect.Map { - panic(fmt.Sprintf("invalid map kind: %v", t)) - } - if _, ok := messageTypeCache.Load(s); ok { - panic(fmt.Errorf("proto: duplicate proto message registered: %s", s)) - } - messageTypeCache.Store(s, t) -} - -// MessageType returns the message type for a named message. -// It returns nil if not found. -// -// Deprecated: Use protoregistry.GlobalTypes.FindMessageByName instead. -func MessageType(s messageName) reflect.Type { - if v, ok := messageTypeCache.Load(s); ok { - return v.(reflect.Type) - } - - // Derive the message type from the v2 registry. - var t reflect.Type - if mt, _ := protoregistry.GlobalTypes.FindMessageByName(protoreflect.FullName(s)); mt != nil { - t = messageGoType(mt) - } - - // If we could not get a concrete type, it is possible that it is a - // pseudo-message for a map entry. - if t == nil { - d, _ := protoregistry.GlobalFiles.FindDescriptorByName(protoreflect.FullName(s)) - if md, _ := d.(protoreflect.MessageDescriptor); md != nil && md.IsMapEntry() { - kt := goTypeForField(md.Fields().ByNumber(1)) - vt := goTypeForField(md.Fields().ByNumber(2)) - t = reflect.MapOf(kt, vt) - } - } - - // Locally cache the message type for the given name. - if t != nil { - v, _ := messageTypeCache.LoadOrStore(s, t) - return v.(reflect.Type) - } - return nil -} - -func goTypeForField(fd protoreflect.FieldDescriptor) reflect.Type { - switch k := fd.Kind(); k { - case protoreflect.EnumKind: - if et, _ := protoregistry.GlobalTypes.FindEnumByName(fd.Enum().FullName()); et != nil { - return enumGoType(et) - } - return reflect.TypeOf(protoreflect.EnumNumber(0)) - case protoreflect.MessageKind, protoreflect.GroupKind: - if mt, _ := protoregistry.GlobalTypes.FindMessageByName(fd.Message().FullName()); mt != nil { - return messageGoType(mt) - } - return reflect.TypeOf((*protoreflect.Message)(nil)).Elem() - default: - return reflect.TypeOf(fd.Default().Interface()) - } -} - -func enumGoType(et protoreflect.EnumType) reflect.Type { - return reflect.TypeOf(et.New(0)) -} - -func messageGoType(mt protoreflect.MessageType) reflect.Type { - return reflect.TypeOf(MessageV1(mt.Zero().Interface())) -} - -// MessageName returns the full protobuf name for the given message type. -// -// Deprecated: Use protoreflect.MessageDescriptor.FullName instead. -func MessageName(m Message) messageName { - if m == nil { - return "" - } - if m, ok := m.(interface{ XXX_MessageName() messageName }); ok { - return m.XXX_MessageName() - } - return messageName(protoimpl.X.MessageDescriptorOf(m).FullName()) -} - -// RegisterExtension is called from the generated code to register -// the extension descriptor. -// -// Deprecated: Use protoregistry.GlobalTypes.RegisterExtension instead. -func RegisterExtension(d *ExtensionDesc) { - if err := protoregistry.GlobalTypes.RegisterExtension(d); err != nil { - panic(err) - } -} - -type extensionsByNumber = map[int32]*ExtensionDesc - -var extensionCache sync.Map // map[messageName]extensionsByNumber - -// RegisteredExtensions returns a map of the registered extensions for the -// provided protobuf message, indexed by the extension field number. -// -// Deprecated: Use protoregistry.GlobalTypes.RangeExtensionsByMessage instead. -func RegisteredExtensions(m Message) extensionsByNumber { - // Check whether the cache is stale. If the number of extensions for - // the given message differs, then it means that some extensions were - // recently registered upstream that we do not know about. - s := MessageName(m) - v, _ := extensionCache.Load(s) - xs, _ := v.(extensionsByNumber) - if protoregistry.GlobalTypes.NumExtensionsByMessage(protoreflect.FullName(s)) == len(xs) { - return xs // cache is up-to-date - } - - // Cache is stale, re-compute the extensions map. - xs = make(extensionsByNumber) - protoregistry.GlobalTypes.RangeExtensionsByMessage(protoreflect.FullName(s), func(xt protoreflect.ExtensionType) bool { - if xd, ok := xt.(*ExtensionDesc); ok { - xs[int32(xt.TypeDescriptor().Number())] = xd - } else { - // TODO: This implies that the protoreflect.ExtensionType is a - // custom type not generated by protoc-gen-go. We could try and - // convert the type to an ExtensionDesc. - } - return true - }) - extensionCache.Store(s, xs) - return xs -} diff --git a/go-controller/vendor/github.com/golang/protobuf/proto/text_decode.go b/go-controller/vendor/github.com/golang/protobuf/proto/text_decode.go deleted file mode 100644 index 47eb3e4450..0000000000 --- a/go-controller/vendor/github.com/golang/protobuf/proto/text_decode.go +++ /dev/null @@ -1,801 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package proto - -import ( - "encoding" - "errors" - "fmt" - "reflect" - "strconv" - "strings" - "unicode/utf8" - - "google.golang.org/protobuf/encoding/prototext" - protoV2 "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/reflect/protoregistry" -) - -const wrapTextUnmarshalV2 = false - -// ParseError is returned by UnmarshalText. -type ParseError struct { - Message string - - // Deprecated: Do not use. - Line, Offset int -} - -func (e *ParseError) Error() string { - if wrapTextUnmarshalV2 { - return e.Message - } - if e.Line == 1 { - return fmt.Sprintf("line 1.%d: %v", e.Offset, e.Message) - } - return fmt.Sprintf("line %d: %v", e.Line, e.Message) -} - -// UnmarshalText parses a proto text formatted string into m. -func UnmarshalText(s string, m Message) error { - if u, ok := m.(encoding.TextUnmarshaler); ok { - return u.UnmarshalText([]byte(s)) - } - - m.Reset() - mi := MessageV2(m) - - if wrapTextUnmarshalV2 { - err := prototext.UnmarshalOptions{ - AllowPartial: true, - }.Unmarshal([]byte(s), mi) - if err != nil { - return &ParseError{Message: err.Error()} - } - return checkRequiredNotSet(mi) - } else { - if err := newTextParser(s).unmarshalMessage(mi.ProtoReflect(), ""); err != nil { - return err - } - return checkRequiredNotSet(mi) - } -} - -type textParser struct { - s string // remaining input - done bool // whether the parsing is finished (success or error) - backed bool // whether back() was called - offset, line int - cur token -} - -type token struct { - value string - err *ParseError - line int // line number - offset int // byte number from start of input, not start of line - unquoted string // the unquoted version of value, if it was a quoted string -} - -func newTextParser(s string) *textParser { - p := new(textParser) - p.s = s - p.line = 1 - p.cur.line = 1 - return p -} - -func (p *textParser) unmarshalMessage(m protoreflect.Message, terminator string) (err error) { - md := m.Descriptor() - fds := md.Fields() - - // A struct is a sequence of "name: value", terminated by one of - // '>' or '}', or the end of the input. A name may also be - // "[extension]" or "[type/url]". - // - // The whole struct can also be an expanded Any message, like: - // [type/url] < ... struct contents ... > - seen := make(map[protoreflect.FieldNumber]bool) - for { - tok := p.next() - if tok.err != nil { - return tok.err - } - if tok.value == terminator { - break - } - if tok.value == "[" { - if err := p.unmarshalExtensionOrAny(m, seen); err != nil { - return err - } - continue - } - - // This is a normal, non-extension field. - name := protoreflect.Name(tok.value) - fd := fds.ByName(name) - switch { - case fd == nil: - gd := fds.ByName(protoreflect.Name(strings.ToLower(string(name)))) - if gd != nil && gd.Kind() == protoreflect.GroupKind && gd.Message().Name() == name { - fd = gd - } - case fd.Kind() == protoreflect.GroupKind && fd.Message().Name() != name: - fd = nil - case fd.IsWeak() && fd.Message().IsPlaceholder(): - fd = nil - } - if fd == nil { - typeName := string(md.FullName()) - if m, ok := m.Interface().(Message); ok { - t := reflect.TypeOf(m) - if t.Kind() == reflect.Ptr { - typeName = t.Elem().String() - } - } - return p.errorf("unknown field name %q in %v", name, typeName) - } - if od := fd.ContainingOneof(); od != nil && m.WhichOneof(od) != nil { - return p.errorf("field '%s' would overwrite already parsed oneof '%s'", name, od.Name()) - } - if fd.Cardinality() != protoreflect.Repeated && seen[fd.Number()] { - return p.errorf("non-repeated field %q was repeated", fd.Name()) - } - seen[fd.Number()] = true - - // Consume any colon. - if err := p.checkForColon(fd); err != nil { - return err - } - - // Parse into the field. - v := m.Get(fd) - if !m.Has(fd) && (fd.IsList() || fd.IsMap() || fd.Message() != nil) { - v = m.Mutable(fd) - } - if v, err = p.unmarshalValue(v, fd); err != nil { - return err - } - m.Set(fd, v) - - if err := p.consumeOptionalSeparator(); err != nil { - return err - } - } - return nil -} - -func (p *textParser) unmarshalExtensionOrAny(m protoreflect.Message, seen map[protoreflect.FieldNumber]bool) error { - name, err := p.consumeExtensionOrAnyName() - if err != nil { - return err - } - - // If it contains a slash, it's an Any type URL. - if slashIdx := strings.LastIndex(name, "/"); slashIdx >= 0 { - tok := p.next() - if tok.err != nil { - return tok.err - } - // consume an optional colon - if tok.value == ":" { - tok = p.next() - if tok.err != nil { - return tok.err - } - } - - var terminator string - switch tok.value { - case "<": - terminator = ">" - case "{": - terminator = "}" - default: - return p.errorf("expected '{' or '<', found %q", tok.value) - } - - mt, err := protoregistry.GlobalTypes.FindMessageByURL(name) - if err != nil { - return p.errorf("unrecognized message %q in google.protobuf.Any", name[slashIdx+len("/"):]) - } - m2 := mt.New() - if err := p.unmarshalMessage(m2, terminator); err != nil { - return err - } - b, err := protoV2.Marshal(m2.Interface()) - if err != nil { - return p.errorf("failed to marshal message of type %q: %v", name[slashIdx+len("/"):], err) - } - - urlFD := m.Descriptor().Fields().ByName("type_url") - valFD := m.Descriptor().Fields().ByName("value") - if seen[urlFD.Number()] { - return p.errorf("Any message unpacked multiple times, or %q already set", urlFD.Name()) - } - if seen[valFD.Number()] { - return p.errorf("Any message unpacked multiple times, or %q already set", valFD.Name()) - } - m.Set(urlFD, protoreflect.ValueOfString(name)) - m.Set(valFD, protoreflect.ValueOfBytes(b)) - seen[urlFD.Number()] = true - seen[valFD.Number()] = true - return nil - } - - xname := protoreflect.FullName(name) - xt, _ := protoregistry.GlobalTypes.FindExtensionByName(xname) - if xt == nil && isMessageSet(m.Descriptor()) { - xt, _ = protoregistry.GlobalTypes.FindExtensionByName(xname.Append("message_set_extension")) - } - if xt == nil { - return p.errorf("unrecognized extension %q", name) - } - fd := xt.TypeDescriptor() - if fd.ContainingMessage().FullName() != m.Descriptor().FullName() { - return p.errorf("extension field %q does not extend message %q", name, m.Descriptor().FullName()) - } - - if err := p.checkForColon(fd); err != nil { - return err - } - - v := m.Get(fd) - if !m.Has(fd) && (fd.IsList() || fd.IsMap() || fd.Message() != nil) { - v = m.Mutable(fd) - } - v, err = p.unmarshalValue(v, fd) - if err != nil { - return err - } - m.Set(fd, v) - return p.consumeOptionalSeparator() -} - -func (p *textParser) unmarshalValue(v protoreflect.Value, fd protoreflect.FieldDescriptor) (protoreflect.Value, error) { - tok := p.next() - if tok.err != nil { - return v, tok.err - } - if tok.value == "" { - return v, p.errorf("unexpected EOF") - } - - switch { - case fd.IsList(): - lv := v.List() - var err error - if tok.value == "[" { - // Repeated field with list notation, like [1,2,3]. - for { - vv := lv.NewElement() - vv, err = p.unmarshalSingularValue(vv, fd) - if err != nil { - return v, err - } - lv.Append(vv) - - tok := p.next() - if tok.err != nil { - return v, tok.err - } - if tok.value == "]" { - break - } - if tok.value != "," { - return v, p.errorf("Expected ']' or ',' found %q", tok.value) - } - } - return v, nil - } - - // One value of the repeated field. - p.back() - vv := lv.NewElement() - vv, err = p.unmarshalSingularValue(vv, fd) - if err != nil { - return v, err - } - lv.Append(vv) - return v, nil - case fd.IsMap(): - // The map entry should be this sequence of tokens: - // < key : KEY value : VALUE > - // However, implementations may omit key or value, and technically - // we should support them in any order. - var terminator string - switch tok.value { - case "<": - terminator = ">" - case "{": - terminator = "}" - default: - return v, p.errorf("expected '{' or '<', found %q", tok.value) - } - - keyFD := fd.MapKey() - valFD := fd.MapValue() - - mv := v.Map() - kv := keyFD.Default() - vv := mv.NewValue() - for { - tok := p.next() - if tok.err != nil { - return v, tok.err - } - if tok.value == terminator { - break - } - var err error - switch tok.value { - case "key": - if err := p.consumeToken(":"); err != nil { - return v, err - } - if kv, err = p.unmarshalSingularValue(kv, keyFD); err != nil { - return v, err - } - if err := p.consumeOptionalSeparator(); err != nil { - return v, err - } - case "value": - if err := p.checkForColon(valFD); err != nil { - return v, err - } - if vv, err = p.unmarshalSingularValue(vv, valFD); err != nil { - return v, err - } - if err := p.consumeOptionalSeparator(); err != nil { - return v, err - } - default: - p.back() - return v, p.errorf(`expected "key", "value", or %q, found %q`, terminator, tok.value) - } - } - mv.Set(kv.MapKey(), vv) - return v, nil - default: - p.back() - return p.unmarshalSingularValue(v, fd) - } -} - -func (p *textParser) unmarshalSingularValue(v protoreflect.Value, fd protoreflect.FieldDescriptor) (protoreflect.Value, error) { - tok := p.next() - if tok.err != nil { - return v, tok.err - } - if tok.value == "" { - return v, p.errorf("unexpected EOF") - } - - switch fd.Kind() { - case protoreflect.BoolKind: - switch tok.value { - case "true", "1", "t", "True": - return protoreflect.ValueOfBool(true), nil - case "false", "0", "f", "False": - return protoreflect.ValueOfBool(false), nil - } - case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind: - if x, err := strconv.ParseInt(tok.value, 0, 32); err == nil { - return protoreflect.ValueOfInt32(int32(x)), nil - } - - // The C++ parser accepts large positive hex numbers that uses - // two's complement arithmetic to represent negative numbers. - // This feature is here for backwards compatibility with C++. - if strings.HasPrefix(tok.value, "0x") { - if x, err := strconv.ParseUint(tok.value, 0, 32); err == nil { - return protoreflect.ValueOfInt32(int32(-(int64(^x) + 1))), nil - } - } - case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind: - if x, err := strconv.ParseInt(tok.value, 0, 64); err == nil { - return protoreflect.ValueOfInt64(int64(x)), nil - } - - // The C++ parser accepts large positive hex numbers that uses - // two's complement arithmetic to represent negative numbers. - // This feature is here for backwards compatibility with C++. - if strings.HasPrefix(tok.value, "0x") { - if x, err := strconv.ParseUint(tok.value, 0, 64); err == nil { - return protoreflect.ValueOfInt64(int64(-(int64(^x) + 1))), nil - } - } - case protoreflect.Uint32Kind, protoreflect.Fixed32Kind: - if x, err := strconv.ParseUint(tok.value, 0, 32); err == nil { - return protoreflect.ValueOfUint32(uint32(x)), nil - } - case protoreflect.Uint64Kind, protoreflect.Fixed64Kind: - if x, err := strconv.ParseUint(tok.value, 0, 64); err == nil { - return protoreflect.ValueOfUint64(uint64(x)), nil - } - case protoreflect.FloatKind: - // Ignore 'f' for compatibility with output generated by C++, - // but don't remove 'f' when the value is "-inf" or "inf". - v := tok.value - if strings.HasSuffix(v, "f") && v != "-inf" && v != "inf" { - v = v[:len(v)-len("f")] - } - if x, err := strconv.ParseFloat(v, 32); err == nil { - return protoreflect.ValueOfFloat32(float32(x)), nil - } - case protoreflect.DoubleKind: - // Ignore 'f' for compatibility with output generated by C++, - // but don't remove 'f' when the value is "-inf" or "inf". - v := tok.value - if strings.HasSuffix(v, "f") && v != "-inf" && v != "inf" { - v = v[:len(v)-len("f")] - } - if x, err := strconv.ParseFloat(v, 64); err == nil { - return protoreflect.ValueOfFloat64(float64(x)), nil - } - case protoreflect.StringKind: - if isQuote(tok.value[0]) { - return protoreflect.ValueOfString(tok.unquoted), nil - } - case protoreflect.BytesKind: - if isQuote(tok.value[0]) { - return protoreflect.ValueOfBytes([]byte(tok.unquoted)), nil - } - case protoreflect.EnumKind: - if x, err := strconv.ParseInt(tok.value, 0, 32); err == nil { - return protoreflect.ValueOfEnum(protoreflect.EnumNumber(x)), nil - } - vd := fd.Enum().Values().ByName(protoreflect.Name(tok.value)) - if vd != nil { - return protoreflect.ValueOfEnum(vd.Number()), nil - } - case protoreflect.MessageKind, protoreflect.GroupKind: - var terminator string - switch tok.value { - case "{": - terminator = "}" - case "<": - terminator = ">" - default: - return v, p.errorf("expected '{' or '<', found %q", tok.value) - } - err := p.unmarshalMessage(v.Message(), terminator) - return v, err - default: - panic(fmt.Sprintf("invalid kind %v", fd.Kind())) - } - return v, p.errorf("invalid %v: %v", fd.Kind(), tok.value) -} - -// Consume a ':' from the input stream (if the next token is a colon), -// returning an error if a colon is needed but not present. -func (p *textParser) checkForColon(fd protoreflect.FieldDescriptor) *ParseError { - tok := p.next() - if tok.err != nil { - return tok.err - } - if tok.value != ":" { - if fd.Message() == nil { - return p.errorf("expected ':', found %q", tok.value) - } - p.back() - } - return nil -} - -// consumeExtensionOrAnyName consumes an extension name or an Any type URL and -// the following ']'. It returns the name or URL consumed. -func (p *textParser) consumeExtensionOrAnyName() (string, error) { - tok := p.next() - if tok.err != nil { - return "", tok.err - } - - // If extension name or type url is quoted, it's a single token. - if len(tok.value) > 2 && isQuote(tok.value[0]) && tok.value[len(tok.value)-1] == tok.value[0] { - name, err := unquoteC(tok.value[1:len(tok.value)-1], rune(tok.value[0])) - if err != nil { - return "", err - } - return name, p.consumeToken("]") - } - - // Consume everything up to "]" - var parts []string - for tok.value != "]" { - parts = append(parts, tok.value) - tok = p.next() - if tok.err != nil { - return "", p.errorf("unrecognized type_url or extension name: %s", tok.err) - } - if p.done && tok.value != "]" { - return "", p.errorf("unclosed type_url or extension name") - } - } - return strings.Join(parts, ""), nil -} - -// consumeOptionalSeparator consumes an optional semicolon or comma. -// It is used in unmarshalMessage to provide backward compatibility. -func (p *textParser) consumeOptionalSeparator() error { - tok := p.next() - if tok.err != nil { - return tok.err - } - if tok.value != ";" && tok.value != "," { - p.back() - } - return nil -} - -func (p *textParser) errorf(format string, a ...interface{}) *ParseError { - pe := &ParseError{fmt.Sprintf(format, a...), p.cur.line, p.cur.offset} - p.cur.err = pe - p.done = true - return pe -} - -func (p *textParser) skipWhitespace() { - i := 0 - for i < len(p.s) && (isWhitespace(p.s[i]) || p.s[i] == '#') { - if p.s[i] == '#' { - // comment; skip to end of line or input - for i < len(p.s) && p.s[i] != '\n' { - i++ - } - if i == len(p.s) { - break - } - } - if p.s[i] == '\n' { - p.line++ - } - i++ - } - p.offset += i - p.s = p.s[i:len(p.s)] - if len(p.s) == 0 { - p.done = true - } -} - -func (p *textParser) advance() { - // Skip whitespace - p.skipWhitespace() - if p.done { - return - } - - // Start of non-whitespace - p.cur.err = nil - p.cur.offset, p.cur.line = p.offset, p.line - p.cur.unquoted = "" - switch p.s[0] { - case '<', '>', '{', '}', ':', '[', ']', ';', ',', '/': - // Single symbol - p.cur.value, p.s = p.s[0:1], p.s[1:len(p.s)] - case '"', '\'': - // Quoted string - i := 1 - for i < len(p.s) && p.s[i] != p.s[0] && p.s[i] != '\n' { - if p.s[i] == '\\' && i+1 < len(p.s) { - // skip escaped char - i++ - } - i++ - } - if i >= len(p.s) || p.s[i] != p.s[0] { - p.errorf("unmatched quote") - return - } - unq, err := unquoteC(p.s[1:i], rune(p.s[0])) - if err != nil { - p.errorf("invalid quoted string %s: %v", p.s[0:i+1], err) - return - } - p.cur.value, p.s = p.s[0:i+1], p.s[i+1:len(p.s)] - p.cur.unquoted = unq - default: - i := 0 - for i < len(p.s) && isIdentOrNumberChar(p.s[i]) { - i++ - } - if i == 0 { - p.errorf("unexpected byte %#x", p.s[0]) - return - } - p.cur.value, p.s = p.s[0:i], p.s[i:len(p.s)] - } - p.offset += len(p.cur.value) -} - -// Back off the parser by one token. Can only be done between calls to next(). -// It makes the next advance() a no-op. -func (p *textParser) back() { p.backed = true } - -// Advances the parser and returns the new current token. -func (p *textParser) next() *token { - if p.backed || p.done { - p.backed = false - return &p.cur - } - p.advance() - if p.done { - p.cur.value = "" - } else if len(p.cur.value) > 0 && isQuote(p.cur.value[0]) { - // Look for multiple quoted strings separated by whitespace, - // and concatenate them. - cat := p.cur - for { - p.skipWhitespace() - if p.done || !isQuote(p.s[0]) { - break - } - p.advance() - if p.cur.err != nil { - return &p.cur - } - cat.value += " " + p.cur.value - cat.unquoted += p.cur.unquoted - } - p.done = false // parser may have seen EOF, but we want to return cat - p.cur = cat - } - return &p.cur -} - -func (p *textParser) consumeToken(s string) error { - tok := p.next() - if tok.err != nil { - return tok.err - } - if tok.value != s { - p.back() - return p.errorf("expected %q, found %q", s, tok.value) - } - return nil -} - -var errBadUTF8 = errors.New("proto: bad UTF-8") - -func unquoteC(s string, quote rune) (string, error) { - // This is based on C++'s tokenizer.cc. - // Despite its name, this is *not* parsing C syntax. - // For instance, "\0" is an invalid quoted string. - - // Avoid allocation in trivial cases. - simple := true - for _, r := range s { - if r == '\\' || r == quote { - simple = false - break - } - } - if simple { - return s, nil - } - - buf := make([]byte, 0, 3*len(s)/2) - for len(s) > 0 { - r, n := utf8.DecodeRuneInString(s) - if r == utf8.RuneError && n == 1 { - return "", errBadUTF8 - } - s = s[n:] - if r != '\\' { - if r < utf8.RuneSelf { - buf = append(buf, byte(r)) - } else { - buf = append(buf, string(r)...) - } - continue - } - - ch, tail, err := unescape(s) - if err != nil { - return "", err - } - buf = append(buf, ch...) - s = tail - } - return string(buf), nil -} - -func unescape(s string) (ch string, tail string, err error) { - r, n := utf8.DecodeRuneInString(s) - if r == utf8.RuneError && n == 1 { - return "", "", errBadUTF8 - } - s = s[n:] - switch r { - case 'a': - return "\a", s, nil - case 'b': - return "\b", s, nil - case 'f': - return "\f", s, nil - case 'n': - return "\n", s, nil - case 'r': - return "\r", s, nil - case 't': - return "\t", s, nil - case 'v': - return "\v", s, nil - case '?': - return "?", s, nil // trigraph workaround - case '\'', '"', '\\': - return string(r), s, nil - case '0', '1', '2', '3', '4', '5', '6', '7': - if len(s) < 2 { - return "", "", fmt.Errorf(`\%c requires 2 following digits`, r) - } - ss := string(r) + s[:2] - s = s[2:] - i, err := strconv.ParseUint(ss, 8, 8) - if err != nil { - return "", "", fmt.Errorf(`\%s contains non-octal digits`, ss) - } - return string([]byte{byte(i)}), s, nil - case 'x', 'X', 'u', 'U': - var n int - switch r { - case 'x', 'X': - n = 2 - case 'u': - n = 4 - case 'U': - n = 8 - } - if len(s) < n { - return "", "", fmt.Errorf(`\%c requires %d following digits`, r, n) - } - ss := s[:n] - s = s[n:] - i, err := strconv.ParseUint(ss, 16, 64) - if err != nil { - return "", "", fmt.Errorf(`\%c%s contains non-hexadecimal digits`, r, ss) - } - if r == 'x' || r == 'X' { - return string([]byte{byte(i)}), s, nil - } - if i > utf8.MaxRune { - return "", "", fmt.Errorf(`\%c%s is not a valid Unicode code point`, r, ss) - } - return string(rune(i)), s, nil - } - return "", "", fmt.Errorf(`unknown escape \%c`, r) -} - -func isIdentOrNumberChar(c byte) bool { - switch { - case 'A' <= c && c <= 'Z', 'a' <= c && c <= 'z': - return true - case '0' <= c && c <= '9': - return true - } - switch c { - case '-', '+', '.', '_': - return true - } - return false -} - -func isWhitespace(c byte) bool { - switch c { - case ' ', '\t', '\n', '\r': - return true - } - return false -} - -func isQuote(c byte) bool { - switch c { - case '"', '\'': - return true - } - return false -} diff --git a/go-controller/vendor/github.com/golang/protobuf/proto/text_encode.go b/go-controller/vendor/github.com/golang/protobuf/proto/text_encode.go deleted file mode 100644 index a31134eeb3..0000000000 --- a/go-controller/vendor/github.com/golang/protobuf/proto/text_encode.go +++ /dev/null @@ -1,560 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package proto - -import ( - "bytes" - "encoding" - "fmt" - "io" - "math" - "sort" - "strings" - - "google.golang.org/protobuf/encoding/prototext" - "google.golang.org/protobuf/encoding/protowire" - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/reflect/protoregistry" -) - -const wrapTextMarshalV2 = false - -// TextMarshaler is a configurable text format marshaler. -type TextMarshaler struct { - Compact bool // use compact text format (one line) - ExpandAny bool // expand google.protobuf.Any messages of known types -} - -// Marshal writes the proto text format of m to w. -func (tm *TextMarshaler) Marshal(w io.Writer, m Message) error { - b, err := tm.marshal(m) - if len(b) > 0 { - if _, err := w.Write(b); err != nil { - return err - } - } - return err -} - -// Text returns a proto text formatted string of m. -func (tm *TextMarshaler) Text(m Message) string { - b, _ := tm.marshal(m) - return string(b) -} - -func (tm *TextMarshaler) marshal(m Message) ([]byte, error) { - mr := MessageReflect(m) - if mr == nil || !mr.IsValid() { - return []byte(""), nil - } - - if wrapTextMarshalV2 { - if m, ok := m.(encoding.TextMarshaler); ok { - return m.MarshalText() - } - - opts := prototext.MarshalOptions{ - AllowPartial: true, - EmitUnknown: true, - } - if !tm.Compact { - opts.Indent = " " - } - if !tm.ExpandAny { - opts.Resolver = (*protoregistry.Types)(nil) - } - return opts.Marshal(mr.Interface()) - } else { - w := &textWriter{ - compact: tm.Compact, - expandAny: tm.ExpandAny, - complete: true, - } - - if m, ok := m.(encoding.TextMarshaler); ok { - b, err := m.MarshalText() - if err != nil { - return nil, err - } - w.Write(b) - return w.buf, nil - } - - err := w.writeMessage(mr) - return w.buf, err - } -} - -var ( - defaultTextMarshaler = TextMarshaler{} - compactTextMarshaler = TextMarshaler{Compact: true} -) - -// MarshalText writes the proto text format of m to w. -func MarshalText(w io.Writer, m Message) error { return defaultTextMarshaler.Marshal(w, m) } - -// MarshalTextString returns a proto text formatted string of m. -func MarshalTextString(m Message) string { return defaultTextMarshaler.Text(m) } - -// CompactText writes the compact proto text format of m to w. -func CompactText(w io.Writer, m Message) error { return compactTextMarshaler.Marshal(w, m) } - -// CompactTextString returns a compact proto text formatted string of m. -func CompactTextString(m Message) string { return compactTextMarshaler.Text(m) } - -var ( - newline = []byte("\n") - endBraceNewline = []byte("}\n") - posInf = []byte("inf") - negInf = []byte("-inf") - nan = []byte("nan") -) - -// textWriter is an io.Writer that tracks its indentation level. -type textWriter struct { - compact bool // same as TextMarshaler.Compact - expandAny bool // same as TextMarshaler.ExpandAny - complete bool // whether the current position is a complete line - indent int // indentation level; never negative - buf []byte -} - -func (w *textWriter) Write(p []byte) (n int, _ error) { - newlines := bytes.Count(p, newline) - if newlines == 0 { - if !w.compact && w.complete { - w.writeIndent() - } - w.buf = append(w.buf, p...) - w.complete = false - return len(p), nil - } - - frags := bytes.SplitN(p, newline, newlines+1) - if w.compact { - for i, frag := range frags { - if i > 0 { - w.buf = append(w.buf, ' ') - n++ - } - w.buf = append(w.buf, frag...) - n += len(frag) - } - return n, nil - } - - for i, frag := range frags { - if w.complete { - w.writeIndent() - } - w.buf = append(w.buf, frag...) - n += len(frag) - if i+1 < len(frags) { - w.buf = append(w.buf, '\n') - n++ - } - } - w.complete = len(frags[len(frags)-1]) == 0 - return n, nil -} - -func (w *textWriter) WriteByte(c byte) error { - if w.compact && c == '\n' { - c = ' ' - } - if !w.compact && w.complete { - w.writeIndent() - } - w.buf = append(w.buf, c) - w.complete = c == '\n' - return nil -} - -func (w *textWriter) writeName(fd protoreflect.FieldDescriptor) { - if !w.compact && w.complete { - w.writeIndent() - } - w.complete = false - - if fd.Kind() != protoreflect.GroupKind { - w.buf = append(w.buf, fd.Name()...) - w.WriteByte(':') - } else { - // Use message type name for group field name. - w.buf = append(w.buf, fd.Message().Name()...) - } - - if !w.compact { - w.WriteByte(' ') - } -} - -func requiresQuotes(u string) bool { - // When type URL contains any characters except [0-9A-Za-z./\-]*, it must be quoted. - for _, ch := range u { - switch { - case ch == '.' || ch == '/' || ch == '_': - continue - case '0' <= ch && ch <= '9': - continue - case 'A' <= ch && ch <= 'Z': - continue - case 'a' <= ch && ch <= 'z': - continue - default: - return true - } - } - return false -} - -// writeProto3Any writes an expanded google.protobuf.Any message. -// -// It returns (false, nil) if sv value can't be unmarshaled (e.g. because -// required messages are not linked in). -// -// It returns (true, error) when sv was written in expanded format or an error -// was encountered. -func (w *textWriter) writeProto3Any(m protoreflect.Message) (bool, error) { - md := m.Descriptor() - fdURL := md.Fields().ByName("type_url") - fdVal := md.Fields().ByName("value") - - url := m.Get(fdURL).String() - mt, err := protoregistry.GlobalTypes.FindMessageByURL(url) - if err != nil { - return false, nil - } - - b := m.Get(fdVal).Bytes() - m2 := mt.New() - if err := proto.Unmarshal(b, m2.Interface()); err != nil { - return false, nil - } - w.Write([]byte("[")) - if requiresQuotes(url) { - w.writeQuotedString(url) - } else { - w.Write([]byte(url)) - } - if w.compact { - w.Write([]byte("]:<")) - } else { - w.Write([]byte("]: <\n")) - w.indent++ - } - if err := w.writeMessage(m2); err != nil { - return true, err - } - if w.compact { - w.Write([]byte("> ")) - } else { - w.indent-- - w.Write([]byte(">\n")) - } - return true, nil -} - -func (w *textWriter) writeMessage(m protoreflect.Message) error { - md := m.Descriptor() - if w.expandAny && md.FullName() == "google.protobuf.Any" { - if canExpand, err := w.writeProto3Any(m); canExpand { - return err - } - } - - fds := md.Fields() - for i := 0; i < fds.Len(); { - fd := fds.Get(i) - if od := fd.ContainingOneof(); od != nil { - fd = m.WhichOneof(od) - i += od.Fields().Len() - } else { - i++ - } - if fd == nil || !m.Has(fd) { - continue - } - - switch { - case fd.IsList(): - lv := m.Get(fd).List() - for j := 0; j < lv.Len(); j++ { - w.writeName(fd) - v := lv.Get(j) - if err := w.writeSingularValue(v, fd); err != nil { - return err - } - w.WriteByte('\n') - } - case fd.IsMap(): - kfd := fd.MapKey() - vfd := fd.MapValue() - mv := m.Get(fd).Map() - - type entry struct{ key, val protoreflect.Value } - var entries []entry - mv.Range(func(k protoreflect.MapKey, v protoreflect.Value) bool { - entries = append(entries, entry{k.Value(), v}) - return true - }) - sort.Slice(entries, func(i, j int) bool { - switch kfd.Kind() { - case protoreflect.BoolKind: - return !entries[i].key.Bool() && entries[j].key.Bool() - case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind, protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind: - return entries[i].key.Int() < entries[j].key.Int() - case protoreflect.Uint32Kind, protoreflect.Fixed32Kind, protoreflect.Uint64Kind, protoreflect.Fixed64Kind: - return entries[i].key.Uint() < entries[j].key.Uint() - case protoreflect.StringKind: - return entries[i].key.String() < entries[j].key.String() - default: - panic("invalid kind") - } - }) - for _, entry := range entries { - w.writeName(fd) - w.WriteByte('<') - if !w.compact { - w.WriteByte('\n') - } - w.indent++ - w.writeName(kfd) - if err := w.writeSingularValue(entry.key, kfd); err != nil { - return err - } - w.WriteByte('\n') - w.writeName(vfd) - if err := w.writeSingularValue(entry.val, vfd); err != nil { - return err - } - w.WriteByte('\n') - w.indent-- - w.WriteByte('>') - w.WriteByte('\n') - } - default: - w.writeName(fd) - if err := w.writeSingularValue(m.Get(fd), fd); err != nil { - return err - } - w.WriteByte('\n') - } - } - - if b := m.GetUnknown(); len(b) > 0 { - w.writeUnknownFields(b) - } - return w.writeExtensions(m) -} - -func (w *textWriter) writeSingularValue(v protoreflect.Value, fd protoreflect.FieldDescriptor) error { - switch fd.Kind() { - case protoreflect.FloatKind, protoreflect.DoubleKind: - switch vf := v.Float(); { - case math.IsInf(vf, +1): - w.Write(posInf) - case math.IsInf(vf, -1): - w.Write(negInf) - case math.IsNaN(vf): - w.Write(nan) - default: - fmt.Fprint(w, v.Interface()) - } - case protoreflect.StringKind: - // NOTE: This does not validate UTF-8 for historical reasons. - w.writeQuotedString(string(v.String())) - case protoreflect.BytesKind: - w.writeQuotedString(string(v.Bytes())) - case protoreflect.MessageKind, protoreflect.GroupKind: - var bra, ket byte = '<', '>' - if fd.Kind() == protoreflect.GroupKind { - bra, ket = '{', '}' - } - w.WriteByte(bra) - if !w.compact { - w.WriteByte('\n') - } - w.indent++ - m := v.Message() - if m2, ok := m.Interface().(encoding.TextMarshaler); ok { - b, err := m2.MarshalText() - if err != nil { - return err - } - w.Write(b) - } else { - w.writeMessage(m) - } - w.indent-- - w.WriteByte(ket) - case protoreflect.EnumKind: - if ev := fd.Enum().Values().ByNumber(v.Enum()); ev != nil { - fmt.Fprint(w, ev.Name()) - } else { - fmt.Fprint(w, v.Enum()) - } - default: - fmt.Fprint(w, v.Interface()) - } - return nil -} - -// writeQuotedString writes a quoted string in the protocol buffer text format. -func (w *textWriter) writeQuotedString(s string) { - w.WriteByte('"') - for i := 0; i < len(s); i++ { - switch c := s[i]; c { - case '\n': - w.buf = append(w.buf, `\n`...) - case '\r': - w.buf = append(w.buf, `\r`...) - case '\t': - w.buf = append(w.buf, `\t`...) - case '"': - w.buf = append(w.buf, `\"`...) - case '\\': - w.buf = append(w.buf, `\\`...) - default: - if isPrint := c >= 0x20 && c < 0x7f; isPrint { - w.buf = append(w.buf, c) - } else { - w.buf = append(w.buf, fmt.Sprintf(`\%03o`, c)...) - } - } - } - w.WriteByte('"') -} - -func (w *textWriter) writeUnknownFields(b []byte) { - if !w.compact { - fmt.Fprintf(w, "/* %d unknown bytes */\n", len(b)) - } - - for len(b) > 0 { - num, wtyp, n := protowire.ConsumeTag(b) - if n < 0 { - return - } - b = b[n:] - - if wtyp == protowire.EndGroupType { - w.indent-- - w.Write(endBraceNewline) - continue - } - fmt.Fprint(w, num) - if wtyp != protowire.StartGroupType { - w.WriteByte(':') - } - if !w.compact || wtyp == protowire.StartGroupType { - w.WriteByte(' ') - } - switch wtyp { - case protowire.VarintType: - v, n := protowire.ConsumeVarint(b) - if n < 0 { - return - } - b = b[n:] - fmt.Fprint(w, v) - case protowire.Fixed32Type: - v, n := protowire.ConsumeFixed32(b) - if n < 0 { - return - } - b = b[n:] - fmt.Fprint(w, v) - case protowire.Fixed64Type: - v, n := protowire.ConsumeFixed64(b) - if n < 0 { - return - } - b = b[n:] - fmt.Fprint(w, v) - case protowire.BytesType: - v, n := protowire.ConsumeBytes(b) - if n < 0 { - return - } - b = b[n:] - fmt.Fprintf(w, "%q", v) - case protowire.StartGroupType: - w.WriteByte('{') - w.indent++ - default: - fmt.Fprintf(w, "/* unknown wire type %d */", wtyp) - } - w.WriteByte('\n') - } -} - -// writeExtensions writes all the extensions in m. -func (w *textWriter) writeExtensions(m protoreflect.Message) error { - md := m.Descriptor() - if md.ExtensionRanges().Len() == 0 { - return nil - } - - type ext struct { - desc protoreflect.FieldDescriptor - val protoreflect.Value - } - var exts []ext - m.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { - if fd.IsExtension() { - exts = append(exts, ext{fd, v}) - } - return true - }) - sort.Slice(exts, func(i, j int) bool { - return exts[i].desc.Number() < exts[j].desc.Number() - }) - - for _, ext := range exts { - // For message set, use the name of the message as the extension name. - name := string(ext.desc.FullName()) - if isMessageSet(ext.desc.ContainingMessage()) { - name = strings.TrimSuffix(name, ".message_set_extension") - } - - if !ext.desc.IsList() { - if err := w.writeSingularExtension(name, ext.val, ext.desc); err != nil { - return err - } - } else { - lv := ext.val.List() - for i := 0; i < lv.Len(); i++ { - if err := w.writeSingularExtension(name, lv.Get(i), ext.desc); err != nil { - return err - } - } - } - } - return nil -} - -func (w *textWriter) writeSingularExtension(name string, v protoreflect.Value, fd protoreflect.FieldDescriptor) error { - fmt.Fprintf(w, "[%s]:", name) - if !w.compact { - w.WriteByte(' ') - } - if err := w.writeSingularValue(v, fd); err != nil { - return err - } - w.WriteByte('\n') - return nil -} - -func (w *textWriter) writeIndent() { - if !w.complete { - return - } - for i := 0; i < w.indent*2; i++ { - w.buf = append(w.buf, ' ') - } - w.complete = false -} diff --git a/go-controller/vendor/github.com/golang/protobuf/proto/wire.go b/go-controller/vendor/github.com/golang/protobuf/proto/wire.go deleted file mode 100644 index d7c28da5a7..0000000000 --- a/go-controller/vendor/github.com/golang/protobuf/proto/wire.go +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package proto - -import ( - protoV2 "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/runtime/protoiface" -) - -// Size returns the size in bytes of the wire-format encoding of m. -func Size(m Message) int { - if m == nil { - return 0 - } - mi := MessageV2(m) - return protoV2.Size(mi) -} - -// Marshal returns the wire-format encoding of m. -func Marshal(m Message) ([]byte, error) { - b, err := marshalAppend(nil, m, false) - if b == nil { - b = zeroBytes - } - return b, err -} - -var zeroBytes = make([]byte, 0, 0) - -func marshalAppend(buf []byte, m Message, deterministic bool) ([]byte, error) { - if m == nil { - return nil, ErrNil - } - mi := MessageV2(m) - nbuf, err := protoV2.MarshalOptions{ - Deterministic: deterministic, - AllowPartial: true, - }.MarshalAppend(buf, mi) - if err != nil { - return buf, err - } - if len(buf) == len(nbuf) { - if !mi.ProtoReflect().IsValid() { - return buf, ErrNil - } - } - return nbuf, checkRequiredNotSet(mi) -} - -// Unmarshal parses a wire-format message in b and places the decoded results in m. -// -// Unmarshal resets m before starting to unmarshal, so any existing data in m is always -// removed. Use UnmarshalMerge to preserve and append to existing data. -func Unmarshal(b []byte, m Message) error { - m.Reset() - return UnmarshalMerge(b, m) -} - -// UnmarshalMerge parses a wire-format message in b and places the decoded results in m. -func UnmarshalMerge(b []byte, m Message) error { - mi := MessageV2(m) - out, err := protoV2.UnmarshalOptions{ - AllowPartial: true, - Merge: true, - }.UnmarshalState(protoiface.UnmarshalInput{ - Buf: b, - Message: mi.ProtoReflect(), - }) - if err != nil { - return err - } - if out.Flags&protoiface.UnmarshalInitialized > 0 { - return nil - } - return checkRequiredNotSet(mi) -} diff --git a/go-controller/vendor/github.com/golang/protobuf/proto/wrappers.go b/go-controller/vendor/github.com/golang/protobuf/proto/wrappers.go deleted file mode 100644 index 398e348599..0000000000 --- a/go-controller/vendor/github.com/golang/protobuf/proto/wrappers.go +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package proto - -// Bool stores v in a new bool value and returns a pointer to it. -func Bool(v bool) *bool { return &v } - -// Int stores v in a new int32 value and returns a pointer to it. -// -// Deprecated: Use Int32 instead. -func Int(v int) *int32 { return Int32(int32(v)) } - -// Int32 stores v in a new int32 value and returns a pointer to it. -func Int32(v int32) *int32 { return &v } - -// Int64 stores v in a new int64 value and returns a pointer to it. -func Int64(v int64) *int64 { return &v } - -// Uint32 stores v in a new uint32 value and returns a pointer to it. -func Uint32(v uint32) *uint32 { return &v } - -// Uint64 stores v in a new uint64 value and returns a pointer to it. -func Uint64(v uint64) *uint64 { return &v } - -// Float32 stores v in a new float32 value and returns a pointer to it. -func Float32(v float32) *float32 { return &v } - -// Float64 stores v in a new float64 value and returns a pointer to it. -func Float64(v float64) *float64 { return &v } - -// String stores v in a new string value and returns a pointer to it. -func String(v string) *string { return &v } diff --git a/go-controller/vendor/github.com/golang/protobuf/ptypes/any.go b/go-controller/vendor/github.com/golang/protobuf/ptypes/any.go deleted file mode 100644 index fdff3fdb4c..0000000000 --- a/go-controller/vendor/github.com/golang/protobuf/ptypes/any.go +++ /dev/null @@ -1,180 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ptypes - -import ( - "fmt" - "strings" - - "github.com/golang/protobuf/proto" - "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/reflect/protoregistry" - - anypb "github.com/golang/protobuf/ptypes/any" -) - -const urlPrefix = "type.googleapis.com/" - -// AnyMessageName returns the message name contained in an anypb.Any message. -// Most type assertions should use the Is function instead. -// -// Deprecated: Call the any.MessageName method instead. -func AnyMessageName(any *anypb.Any) (string, error) { - name, err := anyMessageName(any) - return string(name), err -} -func anyMessageName(any *anypb.Any) (protoreflect.FullName, error) { - if any == nil { - return "", fmt.Errorf("message is nil") - } - name := protoreflect.FullName(any.TypeUrl) - if i := strings.LastIndex(any.TypeUrl, "/"); i >= 0 { - name = name[i+len("/"):] - } - if !name.IsValid() { - return "", fmt.Errorf("message type url %q is invalid", any.TypeUrl) - } - return name, nil -} - -// MarshalAny marshals the given message m into an anypb.Any message. -// -// Deprecated: Call the anypb.New function instead. -func MarshalAny(m proto.Message) (*anypb.Any, error) { - switch dm := m.(type) { - case DynamicAny: - m = dm.Message - case *DynamicAny: - if dm == nil { - return nil, proto.ErrNil - } - m = dm.Message - } - b, err := proto.Marshal(m) - if err != nil { - return nil, err - } - return &anypb.Any{TypeUrl: urlPrefix + proto.MessageName(m), Value: b}, nil -} - -// Empty returns a new message of the type specified in an anypb.Any message. -// It returns protoregistry.NotFound if the corresponding message type could not -// be resolved in the global registry. -// -// Deprecated: Use protoregistry.GlobalTypes.FindMessageByName instead -// to resolve the message name and create a new instance of it. -func Empty(any *anypb.Any) (proto.Message, error) { - name, err := anyMessageName(any) - if err != nil { - return nil, err - } - mt, err := protoregistry.GlobalTypes.FindMessageByName(name) - if err != nil { - return nil, err - } - return proto.MessageV1(mt.New().Interface()), nil -} - -// UnmarshalAny unmarshals the encoded value contained in the anypb.Any message -// into the provided message m. It returns an error if the target message -// does not match the type in the Any message or if an unmarshal error occurs. -// -// The target message m may be a *DynamicAny message. If the underlying message -// type could not be resolved, then this returns protoregistry.NotFound. -// -// Deprecated: Call the any.UnmarshalTo method instead. -func UnmarshalAny(any *anypb.Any, m proto.Message) error { - if dm, ok := m.(*DynamicAny); ok { - if dm.Message == nil { - var err error - dm.Message, err = Empty(any) - if err != nil { - return err - } - } - m = dm.Message - } - - anyName, err := AnyMessageName(any) - if err != nil { - return err - } - msgName := proto.MessageName(m) - if anyName != msgName { - return fmt.Errorf("mismatched message type: got %q want %q", anyName, msgName) - } - return proto.Unmarshal(any.Value, m) -} - -// Is reports whether the Any message contains a message of the specified type. -// -// Deprecated: Call the any.MessageIs method instead. -func Is(any *anypb.Any, m proto.Message) bool { - if any == nil || m == nil { - return false - } - name := proto.MessageName(m) - if !strings.HasSuffix(any.TypeUrl, name) { - return false - } - return len(any.TypeUrl) == len(name) || any.TypeUrl[len(any.TypeUrl)-len(name)-1] == '/' -} - -// DynamicAny is a value that can be passed to UnmarshalAny to automatically -// allocate a proto.Message for the type specified in an anypb.Any message. -// The allocated message is stored in the embedded proto.Message. -// -// Example: -// -// var x ptypes.DynamicAny -// if err := ptypes.UnmarshalAny(a, &x); err != nil { ... } -// fmt.Printf("unmarshaled message: %v", x.Message) -// -// Deprecated: Use the any.UnmarshalNew method instead to unmarshal -// the any message contents into a new instance of the underlying message. -type DynamicAny struct{ proto.Message } - -func (m DynamicAny) String() string { - if m.Message == nil { - return "" - } - return m.Message.String() -} -func (m DynamicAny) Reset() { - if m.Message == nil { - return - } - m.Message.Reset() -} -func (m DynamicAny) ProtoMessage() { - return -} -func (m DynamicAny) ProtoReflect() protoreflect.Message { - if m.Message == nil { - return nil - } - return dynamicAny{proto.MessageReflect(m.Message)} -} - -type dynamicAny struct{ protoreflect.Message } - -func (m dynamicAny) Type() protoreflect.MessageType { - return dynamicAnyType{m.Message.Type()} -} -func (m dynamicAny) New() protoreflect.Message { - return dynamicAnyType{m.Message.Type()}.New() -} -func (m dynamicAny) Interface() protoreflect.ProtoMessage { - return DynamicAny{proto.MessageV1(m.Message.Interface())} -} - -type dynamicAnyType struct{ protoreflect.MessageType } - -func (t dynamicAnyType) New() protoreflect.Message { - return dynamicAny{t.MessageType.New()} -} -func (t dynamicAnyType) Zero() protoreflect.Message { - return dynamicAny{t.MessageType.Zero()} -} diff --git a/go-controller/vendor/github.com/golang/protobuf/ptypes/any/any.pb.go b/go-controller/vendor/github.com/golang/protobuf/ptypes/any/any.pb.go deleted file mode 100644 index 0ef27d33de..0000000000 --- a/go-controller/vendor/github.com/golang/protobuf/ptypes/any/any.pb.go +++ /dev/null @@ -1,62 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: github.com/golang/protobuf/ptypes/any/any.proto - -package any - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - anypb "google.golang.org/protobuf/types/known/anypb" - reflect "reflect" -) - -// Symbols defined in public import of google/protobuf/any.proto. - -type Any = anypb.Any - -var File_github_com_golang_protobuf_ptypes_any_any_proto protoreflect.FileDescriptor - -var file_github_com_golang_protobuf_ptypes_any_any_proto_rawDesc = []byte{ - 0x0a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, - 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x2f, 0x61, 0x6e, 0x79, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x2b, 0x5a, 0x29, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, - 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, - 0x73, 0x2f, 0x61, 0x6e, 0x79, 0x3b, 0x61, 0x6e, 0x79, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, -} - -var file_github_com_golang_protobuf_ptypes_any_any_proto_goTypes = []interface{}{} -var file_github_com_golang_protobuf_ptypes_any_any_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_github_com_golang_protobuf_ptypes_any_any_proto_init() } -func file_github_com_golang_protobuf_ptypes_any_any_proto_init() { - if File_github_com_golang_protobuf_ptypes_any_any_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_github_com_golang_protobuf_ptypes_any_any_proto_rawDesc, - NumEnums: 0, - NumMessages: 0, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_github_com_golang_protobuf_ptypes_any_any_proto_goTypes, - DependencyIndexes: file_github_com_golang_protobuf_ptypes_any_any_proto_depIdxs, - }.Build() - File_github_com_golang_protobuf_ptypes_any_any_proto = out.File - file_github_com_golang_protobuf_ptypes_any_any_proto_rawDesc = nil - file_github_com_golang_protobuf_ptypes_any_any_proto_goTypes = nil - file_github_com_golang_protobuf_ptypes_any_any_proto_depIdxs = nil -} diff --git a/go-controller/vendor/github.com/golang/protobuf/ptypes/doc.go b/go-controller/vendor/github.com/golang/protobuf/ptypes/doc.go deleted file mode 100644 index d3c33259d2..0000000000 --- a/go-controller/vendor/github.com/golang/protobuf/ptypes/doc.go +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package ptypes provides functionality for interacting with well-known types. -// -// Deprecated: Well-known types have specialized functionality directly -// injected into the generated packages for each message type. -// See the deprecation notice for each function for the suggested alternative. -package ptypes diff --git a/go-controller/vendor/github.com/golang/protobuf/ptypes/duration.go b/go-controller/vendor/github.com/golang/protobuf/ptypes/duration.go deleted file mode 100644 index b2b55dd851..0000000000 --- a/go-controller/vendor/github.com/golang/protobuf/ptypes/duration.go +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ptypes - -import ( - "errors" - "fmt" - "time" - - durationpb "github.com/golang/protobuf/ptypes/duration" -) - -// Range of google.protobuf.Duration as specified in duration.proto. -// This is about 10,000 years in seconds. -const ( - maxSeconds = int64(10000 * 365.25 * 24 * 60 * 60) - minSeconds = -maxSeconds -) - -// Duration converts a durationpb.Duration to a time.Duration. -// Duration returns an error if dur is invalid or overflows a time.Duration. -// -// Deprecated: Call the dur.AsDuration and dur.CheckValid methods instead. -func Duration(dur *durationpb.Duration) (time.Duration, error) { - if err := validateDuration(dur); err != nil { - return 0, err - } - d := time.Duration(dur.Seconds) * time.Second - if int64(d/time.Second) != dur.Seconds { - return 0, fmt.Errorf("duration: %v is out of range for time.Duration", dur) - } - if dur.Nanos != 0 { - d += time.Duration(dur.Nanos) * time.Nanosecond - if (d < 0) != (dur.Nanos < 0) { - return 0, fmt.Errorf("duration: %v is out of range for time.Duration", dur) - } - } - return d, nil -} - -// DurationProto converts a time.Duration to a durationpb.Duration. -// -// Deprecated: Call the durationpb.New function instead. -func DurationProto(d time.Duration) *durationpb.Duration { - nanos := d.Nanoseconds() - secs := nanos / 1e9 - nanos -= secs * 1e9 - return &durationpb.Duration{ - Seconds: int64(secs), - Nanos: int32(nanos), - } -} - -// validateDuration determines whether the durationpb.Duration is valid -// according to the definition in google/protobuf/duration.proto. -// A valid durpb.Duration may still be too large to fit into a time.Duration -// Note that the range of durationpb.Duration is about 10,000 years, -// while the range of time.Duration is about 290 years. -func validateDuration(dur *durationpb.Duration) error { - if dur == nil { - return errors.New("duration: nil Duration") - } - if dur.Seconds < minSeconds || dur.Seconds > maxSeconds { - return fmt.Errorf("duration: %v: seconds out of range", dur) - } - if dur.Nanos <= -1e9 || dur.Nanos >= 1e9 { - return fmt.Errorf("duration: %v: nanos out of range", dur) - } - // Seconds and Nanos must have the same sign, unless d.Nanos is zero. - if (dur.Seconds < 0 && dur.Nanos > 0) || (dur.Seconds > 0 && dur.Nanos < 0) { - return fmt.Errorf("duration: %v: seconds and nanos have different signs", dur) - } - return nil -} diff --git a/go-controller/vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go b/go-controller/vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go deleted file mode 100644 index d0079ee3ef..0000000000 --- a/go-controller/vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go +++ /dev/null @@ -1,63 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: github.com/golang/protobuf/ptypes/duration/duration.proto - -package duration - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - durationpb "google.golang.org/protobuf/types/known/durationpb" - reflect "reflect" -) - -// Symbols defined in public import of google/protobuf/duration.proto. - -type Duration = durationpb.Duration - -var File_github_com_golang_protobuf_ptypes_duration_duration_proto protoreflect.FileDescriptor - -var file_github_com_golang_protobuf_ptypes_duration_duration_proto_rawDesc = []byte{ - 0x0a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, - 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x64, 0x75, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x35, 0x5a, 0x33, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var file_github_com_golang_protobuf_ptypes_duration_duration_proto_goTypes = []interface{}{} -var file_github_com_golang_protobuf_ptypes_duration_duration_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_github_com_golang_protobuf_ptypes_duration_duration_proto_init() } -func file_github_com_golang_protobuf_ptypes_duration_duration_proto_init() { - if File_github_com_golang_protobuf_ptypes_duration_duration_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_github_com_golang_protobuf_ptypes_duration_duration_proto_rawDesc, - NumEnums: 0, - NumMessages: 0, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_github_com_golang_protobuf_ptypes_duration_duration_proto_goTypes, - DependencyIndexes: file_github_com_golang_protobuf_ptypes_duration_duration_proto_depIdxs, - }.Build() - File_github_com_golang_protobuf_ptypes_duration_duration_proto = out.File - file_github_com_golang_protobuf_ptypes_duration_duration_proto_rawDesc = nil - file_github_com_golang_protobuf_ptypes_duration_duration_proto_goTypes = nil - file_github_com_golang_protobuf_ptypes_duration_duration_proto_depIdxs = nil -} diff --git a/go-controller/vendor/github.com/golang/protobuf/ptypes/timestamp.go b/go-controller/vendor/github.com/golang/protobuf/ptypes/timestamp.go deleted file mode 100644 index 8368a3f70d..0000000000 --- a/go-controller/vendor/github.com/golang/protobuf/ptypes/timestamp.go +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ptypes - -import ( - "errors" - "fmt" - "time" - - timestamppb "github.com/golang/protobuf/ptypes/timestamp" -) - -// Range of google.protobuf.Duration as specified in timestamp.proto. -const ( - // Seconds field of the earliest valid Timestamp. - // This is time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC).Unix(). - minValidSeconds = -62135596800 - // Seconds field just after the latest valid Timestamp. - // This is time.Date(10000, 1, 1, 0, 0, 0, 0, time.UTC).Unix(). - maxValidSeconds = 253402300800 -) - -// Timestamp converts a timestamppb.Timestamp to a time.Time. -// It returns an error if the argument is invalid. -// -// Unlike most Go functions, if Timestamp returns an error, the first return -// value is not the zero time.Time. Instead, it is the value obtained from the -// time.Unix function when passed the contents of the Timestamp, in the UTC -// locale. This may or may not be a meaningful time; many invalid Timestamps -// do map to valid time.Times. -// -// A nil Timestamp returns an error. The first return value in that case is -// undefined. -// -// Deprecated: Call the ts.AsTime and ts.CheckValid methods instead. -func Timestamp(ts *timestamppb.Timestamp) (time.Time, error) { - // Don't return the zero value on error, because corresponds to a valid - // timestamp. Instead return whatever time.Unix gives us. - var t time.Time - if ts == nil { - t = time.Unix(0, 0).UTC() // treat nil like the empty Timestamp - } else { - t = time.Unix(ts.Seconds, int64(ts.Nanos)).UTC() - } - return t, validateTimestamp(ts) -} - -// TimestampNow returns a google.protobuf.Timestamp for the current time. -// -// Deprecated: Call the timestamppb.Now function instead. -func TimestampNow() *timestamppb.Timestamp { - ts, err := TimestampProto(time.Now()) - if err != nil { - panic("ptypes: time.Now() out of Timestamp range") - } - return ts -} - -// TimestampProto converts the time.Time to a google.protobuf.Timestamp proto. -// It returns an error if the resulting Timestamp is invalid. -// -// Deprecated: Call the timestamppb.New function instead. -func TimestampProto(t time.Time) (*timestamppb.Timestamp, error) { - ts := ×tamppb.Timestamp{ - Seconds: t.Unix(), - Nanos: int32(t.Nanosecond()), - } - if err := validateTimestamp(ts); err != nil { - return nil, err - } - return ts, nil -} - -// TimestampString returns the RFC 3339 string for valid Timestamps. -// For invalid Timestamps, it returns an error message in parentheses. -// -// Deprecated: Call the ts.AsTime method instead, -// followed by a call to the Format method on the time.Time value. -func TimestampString(ts *timestamppb.Timestamp) string { - t, err := Timestamp(ts) - if err != nil { - return fmt.Sprintf("(%v)", err) - } - return t.Format(time.RFC3339Nano) -} - -// validateTimestamp determines whether a Timestamp is valid. -// A valid timestamp represents a time in the range [0001-01-01, 10000-01-01) -// and has a Nanos field in the range [0, 1e9). -// -// If the Timestamp is valid, validateTimestamp returns nil. -// Otherwise, it returns an error that describes the problem. -// -// Every valid Timestamp can be represented by a time.Time, -// but the converse is not true. -func validateTimestamp(ts *timestamppb.Timestamp) error { - if ts == nil { - return errors.New("timestamp: nil Timestamp") - } - if ts.Seconds < minValidSeconds { - return fmt.Errorf("timestamp: %v before 0001-01-01", ts) - } - if ts.Seconds >= maxValidSeconds { - return fmt.Errorf("timestamp: %v after 10000-01-01", ts) - } - if ts.Nanos < 0 || ts.Nanos >= 1e9 { - return fmt.Errorf("timestamp: %v: nanos not in range [0, 1e9)", ts) - } - return nil -} diff --git a/go-controller/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go b/go-controller/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go deleted file mode 100644 index a76f807600..0000000000 --- a/go-controller/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go +++ /dev/null @@ -1,64 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: github.com/golang/protobuf/ptypes/timestamp/timestamp.proto - -package timestamp - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - timestamppb "google.golang.org/protobuf/types/known/timestamppb" - reflect "reflect" -) - -// Symbols defined in public import of google/protobuf/timestamp.proto. - -type Timestamp = timestamppb.Timestamp - -var File_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto protoreflect.FileDescriptor - -var file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_rawDesc = []byte{ - 0x0a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, - 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2f, 0x74, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x37, - 0x5a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, - 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x3b, 0x74, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, -} - -var file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_goTypes = []interface{}{} -var file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_init() } -func file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_init() { - if File_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_rawDesc, - NumEnums: 0, - NumMessages: 0, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_goTypes, - DependencyIndexes: file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_depIdxs, - }.Build() - File_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto = out.File - file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_rawDesc = nil - file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_goTypes = nil - file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_depIdxs = nil -} diff --git a/go-controller/vendor/github.com/google/gnostic-models/compiler/extensions.go b/go-controller/vendor/github.com/google/gnostic-models/compiler/extensions.go index 250c81e8c8..16ae66faa3 100644 --- a/go-controller/vendor/github.com/google/gnostic-models/compiler/extensions.go +++ b/go-controller/vendor/github.com/google/gnostic-models/compiler/extensions.go @@ -20,8 +20,8 @@ import ( "os/exec" "strings" - "github.com/golang/protobuf/proto" - "github.com/golang/protobuf/ptypes/any" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/known/anypb" yaml "gopkg.in/yaml.v3" extensions "github.com/google/gnostic-models/extensions" @@ -33,7 +33,7 @@ type ExtensionHandler struct { } // CallExtension calls a binary extension handler. -func CallExtension(context *Context, in *yaml.Node, extensionName string) (handled bool, response *any.Any, err error) { +func CallExtension(context *Context, in *yaml.Node, extensionName string) (handled bool, response *anypb.Any, err error) { if context == nil || context.ExtensionHandlers == nil { return false, nil, nil } @@ -50,7 +50,7 @@ func CallExtension(context *Context, in *yaml.Node, extensionName string) (handl return handled, response, err } -func (extensionHandlers *ExtensionHandler) handle(in *yaml.Node, extensionName string) (*any.Any, error) { +func (extensionHandlers *ExtensionHandler) handle(in *yaml.Node, extensionName string) (*anypb.Any, error) { if extensionHandlers.Name != "" { yamlData, _ := yaml.Marshal(in) request := &extensions.ExtensionHandlerRequest{ diff --git a/go-controller/vendor/github.com/google/gnostic-models/extensions/extension.pb.go b/go-controller/vendor/github.com/google/gnostic-models/extensions/extension.pb.go index a71df8abec..16c40d985f 100644 --- a/go-controller/vendor/github.com/google/gnostic-models/extensions/extension.pb.go +++ b/go-controller/vendor/github.com/google/gnostic-models/extensions/extension.pb.go @@ -14,8 +14,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.27.1 -// protoc v3.19.3 +// protoc-gen-go v1.35.1 +// protoc v4.23.4 // source: extensions/extension.proto package gnostic_extension_v1 @@ -51,11 +51,9 @@ type Version struct { func (x *Version) Reset() { *x = Version{} - if protoimpl.UnsafeEnabled { - mi := &file_extensions_extension_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_extensions_extension_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Version) String() string { @@ -66,7 +64,7 @@ func (*Version) ProtoMessage() {} func (x *Version) ProtoReflect() protoreflect.Message { mi := &file_extensions_extension_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -123,11 +121,9 @@ type ExtensionHandlerRequest struct { func (x *ExtensionHandlerRequest) Reset() { *x = ExtensionHandlerRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_extensions_extension_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_extensions_extension_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ExtensionHandlerRequest) String() string { @@ -138,7 +134,7 @@ func (*ExtensionHandlerRequest) ProtoMessage() {} func (x *ExtensionHandlerRequest) ProtoReflect() protoreflect.Message { mi := &file_extensions_extension_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -191,11 +187,9 @@ type ExtensionHandlerResponse struct { func (x *ExtensionHandlerResponse) Reset() { *x = ExtensionHandlerResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_extensions_extension_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_extensions_extension_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ExtensionHandlerResponse) String() string { @@ -206,7 +200,7 @@ func (*ExtensionHandlerResponse) ProtoMessage() {} func (x *ExtensionHandlerResponse) ProtoReflect() protoreflect.Message { mi := &file_extensions_extension_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -257,11 +251,9 @@ type Wrapper struct { func (x *Wrapper) Reset() { *x = Wrapper{} - if protoimpl.UnsafeEnabled { - mi := &file_extensions_extension_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_extensions_extension_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Wrapper) String() string { @@ -272,7 +264,7 @@ func (*Wrapper) ProtoMessage() {} func (x *Wrapper) ProtoReflect() protoreflect.Message { mi := &file_extensions_extension_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -367,7 +359,7 @@ func file_extensions_extension_proto_rawDescGZIP() []byte { } var file_extensions_extension_proto_msgTypes = make([]protoimpl.MessageInfo, 4) -var file_extensions_extension_proto_goTypes = []interface{}{ +var file_extensions_extension_proto_goTypes = []any{ (*Version)(nil), // 0: gnostic.extension.v1.Version (*ExtensionHandlerRequest)(nil), // 1: gnostic.extension.v1.ExtensionHandlerRequest (*ExtensionHandlerResponse)(nil), // 2: gnostic.extension.v1.ExtensionHandlerResponse @@ -390,56 +382,6 @@ func file_extensions_extension_proto_init() { if File_extensions_extension_proto != nil { return } - if !protoimpl.UnsafeEnabled { - file_extensions_extension_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Version); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_extensions_extension_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ExtensionHandlerRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_extensions_extension_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ExtensionHandlerResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_extensions_extension_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Wrapper); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ diff --git a/go-controller/vendor/github.com/google/gnostic-models/extensions/extensions.go b/go-controller/vendor/github.com/google/gnostic-models/extensions/extensions.go index ec8afd0092..0768163e5a 100644 --- a/go-controller/vendor/github.com/google/gnostic-models/extensions/extensions.go +++ b/go-controller/vendor/github.com/google/gnostic-models/extensions/extensions.go @@ -19,8 +19,8 @@ import ( "log" "os" - "github.com/golang/protobuf/proto" - "github.com/golang/protobuf/ptypes" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/known/anypb" ) type extensionHandler func(name string, yamlInput string) (bool, proto.Message, error) @@ -54,7 +54,7 @@ func Main(handler extensionHandler) { response.Errors = append(response.Errors, err.Error()) } else if handled { response.Handled = true - response.Value, err = ptypes.MarshalAny(output) + response.Value, err = anypb.New(output) if err != nil { response.Errors = append(response.Errors, err.Error()) } diff --git a/go-controller/vendor/github.com/google/gnostic-models/openapiv2/OpenAPIv2.pb.go b/go-controller/vendor/github.com/google/gnostic-models/openapiv2/OpenAPIv2.pb.go index 65c4c913ce..3b930b3de2 100644 --- a/go-controller/vendor/github.com/google/gnostic-models/openapiv2/OpenAPIv2.pb.go +++ b/go-controller/vendor/github.com/google/gnostic-models/openapiv2/OpenAPIv2.pb.go @@ -16,8 +16,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.27.1 -// protoc v3.19.3 +// protoc-gen-go v1.35.1 +// protoc v4.23.4 // source: openapiv2/OpenAPIv2.proto package openapi_v2 @@ -43,6 +43,7 @@ type AdditionalPropertiesItem struct { unknownFields protoimpl.UnknownFields // Types that are assignable to Oneof: + // // *AdditionalPropertiesItem_Schema // *AdditionalPropertiesItem_Boolean Oneof isAdditionalPropertiesItem_Oneof `protobuf_oneof:"oneof"` @@ -50,11 +51,9 @@ type AdditionalPropertiesItem struct { func (x *AdditionalPropertiesItem) Reset() { *x = AdditionalPropertiesItem{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *AdditionalPropertiesItem) String() string { @@ -65,7 +64,7 @@ func (*AdditionalPropertiesItem) ProtoMessage() {} func (x *AdditionalPropertiesItem) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -128,11 +127,9 @@ type Any struct { func (x *Any) Reset() { *x = Any{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Any) String() string { @@ -143,7 +140,7 @@ func (*Any) ProtoMessage() {} func (x *Any) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -186,11 +183,9 @@ type ApiKeySecurity struct { func (x *ApiKeySecurity) Reset() { *x = ApiKeySecurity{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ApiKeySecurity) String() string { @@ -201,7 +196,7 @@ func (*ApiKeySecurity) ProtoMessage() {} func (x *ApiKeySecurity) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -263,11 +258,9 @@ type BasicAuthenticationSecurity struct { func (x *BasicAuthenticationSecurity) Reset() { *x = BasicAuthenticationSecurity{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *BasicAuthenticationSecurity) String() string { @@ -278,7 +271,7 @@ func (*BasicAuthenticationSecurity) ProtoMessage() {} func (x *BasicAuthenticationSecurity) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -333,11 +326,9 @@ type BodyParameter struct { func (x *BodyParameter) Reset() { *x = BodyParameter{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *BodyParameter) String() string { @@ -348,7 +339,7 @@ func (*BodyParameter) ProtoMessage() {} func (x *BodyParameter) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -422,11 +413,9 @@ type Contact struct { func (x *Contact) Reset() { *x = Contact{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Contact) String() string { @@ -437,7 +426,7 @@ func (*Contact) ProtoMessage() {} func (x *Contact) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -490,11 +479,9 @@ type Default struct { func (x *Default) Reset() { *x = Default{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Default) String() string { @@ -505,7 +492,7 @@ func (*Default) ProtoMessage() {} func (x *Default) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -538,11 +525,9 @@ type Definitions struct { func (x *Definitions) Reset() { *x = Definitions{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Definitions) String() string { @@ -553,7 +538,7 @@ func (*Definitions) ProtoMessage() {} func (x *Definitions) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -606,11 +591,9 @@ type Document struct { func (x *Document) Reset() { *x = Document{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Document) String() string { @@ -621,7 +604,7 @@ func (*Document) ProtoMessage() {} func (x *Document) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -758,11 +741,9 @@ type Examples struct { func (x *Examples) Reset() { *x = Examples{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Examples) String() string { @@ -773,7 +754,7 @@ func (*Examples) ProtoMessage() {} func (x *Examples) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -808,11 +789,9 @@ type ExternalDocs struct { func (x *ExternalDocs) Reset() { *x = ExternalDocs{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ExternalDocs) String() string { @@ -823,7 +802,7 @@ func (*ExternalDocs) ProtoMessage() {} func (x *ExternalDocs) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -879,11 +858,9 @@ type FileSchema struct { func (x *FileSchema) Reset() { *x = FileSchema{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *FileSchema) String() string { @@ -894,7 +871,7 @@ func (*FileSchema) ProtoMessage() {} func (x *FileSchema) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1016,11 +993,9 @@ type FormDataParameterSubSchema struct { func (x *FormDataParameterSubSchema) Reset() { *x = FormDataParameterSubSchema{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *FormDataParameterSubSchema) String() string { @@ -1031,7 +1006,7 @@ func (*FormDataParameterSubSchema) ProtoMessage() {} func (x *FormDataParameterSubSchema) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1235,11 +1210,9 @@ type Header struct { func (x *Header) Reset() { *x = Header{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Header) String() string { @@ -1250,7 +1223,7 @@ func (*Header) ProtoMessage() {} func (x *Header) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[13] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1433,11 +1406,9 @@ type HeaderParameterSubSchema struct { func (x *HeaderParameterSubSchema) Reset() { *x = HeaderParameterSubSchema{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *HeaderParameterSubSchema) String() string { @@ -1448,7 +1419,7 @@ func (*HeaderParameterSubSchema) ProtoMessage() {} func (x *HeaderParameterSubSchema) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[14] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1627,11 +1598,9 @@ type Headers struct { func (x *Headers) Reset() { *x = Headers{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[15] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Headers) String() string { @@ -1642,7 +1611,7 @@ func (*Headers) ProtoMessage() {} func (x *Headers) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[15] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1685,11 +1654,9 @@ type Info struct { func (x *Info) Reset() { *x = Info{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[16] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Info) String() string { @@ -1700,7 +1667,7 @@ func (*Info) ProtoMessage() {} func (x *Info) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[16] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1774,11 +1741,9 @@ type ItemsItem struct { func (x *ItemsItem) Reset() { *x = ItemsItem{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[17] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ItemsItem) String() string { @@ -1789,7 +1754,7 @@ func (*ItemsItem) ProtoMessage() {} func (x *ItemsItem) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[17] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1822,11 +1787,9 @@ type JsonReference struct { func (x *JsonReference) Reset() { *x = JsonReference{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[18] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *JsonReference) String() string { @@ -1837,7 +1800,7 @@ func (*JsonReference) ProtoMessage() {} func (x *JsonReference) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[18] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1880,11 +1843,9 @@ type License struct { func (x *License) Reset() { *x = License{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[19] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *License) String() string { @@ -1895,7 +1856,7 @@ func (*License) ProtoMessage() {} func (x *License) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[19] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1945,11 +1906,9 @@ type NamedAny struct { func (x *NamedAny) Reset() { *x = NamedAny{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[20] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *NamedAny) String() string { @@ -1960,7 +1919,7 @@ func (*NamedAny) ProtoMessage() {} func (x *NamedAny) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[20] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2003,11 +1962,9 @@ type NamedHeader struct { func (x *NamedHeader) Reset() { *x = NamedHeader{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[21] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *NamedHeader) String() string { @@ -2018,7 +1975,7 @@ func (*NamedHeader) ProtoMessage() {} func (x *NamedHeader) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[21] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2061,11 +2018,9 @@ type NamedParameter struct { func (x *NamedParameter) Reset() { *x = NamedParameter{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[22] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *NamedParameter) String() string { @@ -2076,7 +2031,7 @@ func (*NamedParameter) ProtoMessage() {} func (x *NamedParameter) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[22] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2119,11 +2074,9 @@ type NamedPathItem struct { func (x *NamedPathItem) Reset() { *x = NamedPathItem{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[23] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *NamedPathItem) String() string { @@ -2134,7 +2087,7 @@ func (*NamedPathItem) ProtoMessage() {} func (x *NamedPathItem) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[23] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2177,11 +2130,9 @@ type NamedResponse struct { func (x *NamedResponse) Reset() { *x = NamedResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[24] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *NamedResponse) String() string { @@ -2192,7 +2143,7 @@ func (*NamedResponse) ProtoMessage() {} func (x *NamedResponse) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[24] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2235,11 +2186,9 @@ type NamedResponseValue struct { func (x *NamedResponseValue) Reset() { *x = NamedResponseValue{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[25] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *NamedResponseValue) String() string { @@ -2250,7 +2199,7 @@ func (*NamedResponseValue) ProtoMessage() {} func (x *NamedResponseValue) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[25] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2293,11 +2242,9 @@ type NamedSchema struct { func (x *NamedSchema) Reset() { *x = NamedSchema{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[26] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *NamedSchema) String() string { @@ -2308,7 +2255,7 @@ func (*NamedSchema) ProtoMessage() {} func (x *NamedSchema) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[26] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2351,11 +2298,9 @@ type NamedSecurityDefinitionsItem struct { func (x *NamedSecurityDefinitionsItem) Reset() { *x = NamedSecurityDefinitionsItem{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[27] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *NamedSecurityDefinitionsItem) String() string { @@ -2366,7 +2311,7 @@ func (*NamedSecurityDefinitionsItem) ProtoMessage() {} func (x *NamedSecurityDefinitionsItem) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[27] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2409,11 +2354,9 @@ type NamedString struct { func (x *NamedString) Reset() { *x = NamedString{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[28] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *NamedString) String() string { @@ -2424,7 +2367,7 @@ func (*NamedString) ProtoMessage() {} func (x *NamedString) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[28] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2467,11 +2410,9 @@ type NamedStringArray struct { func (x *NamedStringArray) Reset() { *x = NamedStringArray{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[29] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *NamedStringArray) String() string { @@ -2482,7 +2423,7 @@ func (*NamedStringArray) ProtoMessage() {} func (x *NamedStringArray) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[29] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2517,6 +2458,7 @@ type NonBodyParameter struct { unknownFields protoimpl.UnknownFields // Types that are assignable to Oneof: + // // *NonBodyParameter_HeaderParameterSubSchema // *NonBodyParameter_FormDataParameterSubSchema // *NonBodyParameter_QueryParameterSubSchema @@ -2526,11 +2468,9 @@ type NonBodyParameter struct { func (x *NonBodyParameter) Reset() { *x = NonBodyParameter{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[30] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *NonBodyParameter) String() string { @@ -2541,7 +2481,7 @@ func (*NonBodyParameter) ProtoMessage() {} func (x *NonBodyParameter) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[30] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2635,11 +2575,9 @@ type Oauth2AccessCodeSecurity struct { func (x *Oauth2AccessCodeSecurity) Reset() { *x = Oauth2AccessCodeSecurity{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[31] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[31] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Oauth2AccessCodeSecurity) String() string { @@ -2650,7 +2588,7 @@ func (*Oauth2AccessCodeSecurity) ProtoMessage() {} func (x *Oauth2AccessCodeSecurity) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[31] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2729,11 +2667,9 @@ type Oauth2ApplicationSecurity struct { func (x *Oauth2ApplicationSecurity) Reset() { *x = Oauth2ApplicationSecurity{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[32] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[32] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Oauth2ApplicationSecurity) String() string { @@ -2744,7 +2680,7 @@ func (*Oauth2ApplicationSecurity) ProtoMessage() {} func (x *Oauth2ApplicationSecurity) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[32] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2816,11 +2752,9 @@ type Oauth2ImplicitSecurity struct { func (x *Oauth2ImplicitSecurity) Reset() { *x = Oauth2ImplicitSecurity{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[33] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[33] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Oauth2ImplicitSecurity) String() string { @@ -2831,7 +2765,7 @@ func (*Oauth2ImplicitSecurity) ProtoMessage() {} func (x *Oauth2ImplicitSecurity) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[33] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2903,11 +2837,9 @@ type Oauth2PasswordSecurity struct { func (x *Oauth2PasswordSecurity) Reset() { *x = Oauth2PasswordSecurity{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[34] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[34] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Oauth2PasswordSecurity) String() string { @@ -2918,7 +2850,7 @@ func (*Oauth2PasswordSecurity) ProtoMessage() {} func (x *Oauth2PasswordSecurity) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[34] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2985,11 +2917,9 @@ type Oauth2Scopes struct { func (x *Oauth2Scopes) Reset() { *x = Oauth2Scopes{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[35] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[35] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Oauth2Scopes) String() string { @@ -3000,7 +2930,7 @@ func (*Oauth2Scopes) ProtoMessage() {} func (x *Oauth2Scopes) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[35] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3051,11 +2981,9 @@ type Operation struct { func (x *Operation) Reset() { *x = Operation{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[36] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[36] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Operation) String() string { @@ -3066,7 +2994,7 @@ func (*Operation) ProtoMessage() {} func (x *Operation) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[36] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3178,6 +3106,7 @@ type Parameter struct { unknownFields protoimpl.UnknownFields // Types that are assignable to Oneof: + // // *Parameter_BodyParameter // *Parameter_NonBodyParameter Oneof isParameter_Oneof `protobuf_oneof:"oneof"` @@ -3185,11 +3114,9 @@ type Parameter struct { func (x *Parameter) Reset() { *x = Parameter{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[37] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[37] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Parameter) String() string { @@ -3200,7 +3127,7 @@ func (*Parameter) ProtoMessage() {} func (x *Parameter) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[37] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3263,11 +3190,9 @@ type ParameterDefinitions struct { func (x *ParameterDefinitions) Reset() { *x = ParameterDefinitions{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[38] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[38] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ParameterDefinitions) String() string { @@ -3278,7 +3203,7 @@ func (*ParameterDefinitions) ProtoMessage() {} func (x *ParameterDefinitions) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[38] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3306,6 +3231,7 @@ type ParametersItem struct { unknownFields protoimpl.UnknownFields // Types that are assignable to Oneof: + // // *ParametersItem_Parameter // *ParametersItem_JsonReference Oneof isParametersItem_Oneof `protobuf_oneof:"oneof"` @@ -3313,11 +3239,9 @@ type ParametersItem struct { func (x *ParametersItem) Reset() { *x = ParametersItem{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[39] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[39] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ParametersItem) String() string { @@ -3328,7 +3252,7 @@ func (*ParametersItem) ProtoMessage() {} func (x *ParametersItem) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[39] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3400,11 +3324,9 @@ type PathItem struct { func (x *PathItem) Reset() { *x = PathItem{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[40] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[40] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *PathItem) String() string { @@ -3415,7 +3337,7 @@ func (*PathItem) ProtoMessage() {} func (x *PathItem) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[40] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3535,11 +3457,9 @@ type PathParameterSubSchema struct { func (x *PathParameterSubSchema) Reset() { *x = PathParameterSubSchema{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[41] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[41] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *PathParameterSubSchema) String() string { @@ -3550,7 +3470,7 @@ func (*PathParameterSubSchema) ProtoMessage() {} func (x *PathParameterSubSchema) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[41] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3731,11 +3651,9 @@ type Paths struct { func (x *Paths) Reset() { *x = Paths{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[42] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[42] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Paths) String() string { @@ -3746,7 +3664,7 @@ func (*Paths) ProtoMessage() {} func (x *Paths) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[42] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3802,11 +3720,9 @@ type PrimitivesItems struct { func (x *PrimitivesItems) Reset() { *x = PrimitivesItems{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[43] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[43] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *PrimitivesItems) String() string { @@ -3817,7 +3733,7 @@ func (*PrimitivesItems) ProtoMessage() {} func (x *PrimitivesItems) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[43] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3968,11 +3884,9 @@ type Properties struct { func (x *Properties) Reset() { *x = Properties{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[44] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[44] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Properties) String() string { @@ -3983,7 +3897,7 @@ func (*Properties) ProtoMessage() {} func (x *Properties) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[44] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4042,11 +3956,9 @@ type QueryParameterSubSchema struct { func (x *QueryParameterSubSchema) Reset() { *x = QueryParameterSubSchema{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[45] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[45] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *QueryParameterSubSchema) String() string { @@ -4057,7 +3969,7 @@ func (*QueryParameterSubSchema) ProtoMessage() {} func (x *QueryParameterSubSchema) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[45] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4247,11 +4159,9 @@ type Response struct { func (x *Response) Reset() { *x = Response{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[46] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[46] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Response) String() string { @@ -4262,7 +4172,7 @@ func (*Response) ProtoMessage() {} func (x *Response) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[46] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4323,11 +4233,9 @@ type ResponseDefinitions struct { func (x *ResponseDefinitions) Reset() { *x = ResponseDefinitions{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[47] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[47] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ResponseDefinitions) String() string { @@ -4338,7 +4246,7 @@ func (*ResponseDefinitions) ProtoMessage() {} func (x *ResponseDefinitions) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[47] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4366,6 +4274,7 @@ type ResponseValue struct { unknownFields protoimpl.UnknownFields // Types that are assignable to Oneof: + // // *ResponseValue_Response // *ResponseValue_JsonReference Oneof isResponseValue_Oneof `protobuf_oneof:"oneof"` @@ -4373,11 +4282,9 @@ type ResponseValue struct { func (x *ResponseValue) Reset() { *x = ResponseValue{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[48] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[48] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ResponseValue) String() string { @@ -4388,7 +4295,7 @@ func (*ResponseValue) ProtoMessage() {} func (x *ResponseValue) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[48] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4452,11 +4359,9 @@ type Responses struct { func (x *Responses) Reset() { *x = Responses{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[49] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[49] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Responses) String() string { @@ -4467,7 +4372,7 @@ func (*Responses) ProtoMessage() {} func (x *Responses) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[49] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4537,11 +4442,9 @@ type Schema struct { func (x *Schema) Reset() { *x = Schema{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[50] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[50] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Schema) String() string { @@ -4552,7 +4455,7 @@ func (*Schema) ProtoMessage() {} func (x *Schema) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[50] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4790,6 +4693,7 @@ type SchemaItem struct { unknownFields protoimpl.UnknownFields // Types that are assignable to Oneof: + // // *SchemaItem_Schema // *SchemaItem_FileSchema Oneof isSchemaItem_Oneof `protobuf_oneof:"oneof"` @@ -4797,11 +4701,9 @@ type SchemaItem struct { func (x *SchemaItem) Reset() { *x = SchemaItem{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[51] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[51] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SchemaItem) String() string { @@ -4812,7 +4714,7 @@ func (*SchemaItem) ProtoMessage() {} func (x *SchemaItem) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[51] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4874,11 +4776,9 @@ type SecurityDefinitions struct { func (x *SecurityDefinitions) Reset() { *x = SecurityDefinitions{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[52] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[52] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SecurityDefinitions) String() string { @@ -4889,7 +4789,7 @@ func (*SecurityDefinitions) ProtoMessage() {} func (x *SecurityDefinitions) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[52] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4917,6 +4817,7 @@ type SecurityDefinitionsItem struct { unknownFields protoimpl.UnknownFields // Types that are assignable to Oneof: + // // *SecurityDefinitionsItem_BasicAuthenticationSecurity // *SecurityDefinitionsItem_ApiKeySecurity // *SecurityDefinitionsItem_Oauth2ImplicitSecurity @@ -4928,11 +4829,9 @@ type SecurityDefinitionsItem struct { func (x *SecurityDefinitionsItem) Reset() { *x = SecurityDefinitionsItem{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[53] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[53] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SecurityDefinitionsItem) String() string { @@ -4943,7 +4842,7 @@ func (*SecurityDefinitionsItem) ProtoMessage() {} func (x *SecurityDefinitionsItem) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[53] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -5057,11 +4956,9 @@ type SecurityRequirement struct { func (x *SecurityRequirement) Reset() { *x = SecurityRequirement{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[54] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[54] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SecurityRequirement) String() string { @@ -5072,7 +4969,7 @@ func (*SecurityRequirement) ProtoMessage() {} func (x *SecurityRequirement) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[54] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -5104,11 +5001,9 @@ type StringArray struct { func (x *StringArray) Reset() { *x = StringArray{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[55] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[55] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *StringArray) String() string { @@ -5119,7 +5014,7 @@ func (*StringArray) ProtoMessage() {} func (x *StringArray) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[55] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -5154,11 +5049,9 @@ type Tag struct { func (x *Tag) Reset() { *x = Tag{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[56] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[56] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Tag) String() string { @@ -5169,7 +5062,7 @@ func (*Tag) ProtoMessage() {} func (x *Tag) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[56] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -5222,11 +5115,9 @@ type TypeItem struct { func (x *TypeItem) Reset() { *x = TypeItem{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[57] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[57] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *TypeItem) String() string { @@ -5237,7 +5128,7 @@ func (*TypeItem) ProtoMessage() {} func (x *TypeItem) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[57] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -5270,11 +5161,9 @@ type VendorExtension struct { func (x *VendorExtension) Reset() { *x = VendorExtension{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[58] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[58] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *VendorExtension) String() string { @@ -5285,7 +5174,7 @@ func (*VendorExtension) ProtoMessage() {} func (x *VendorExtension) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[58] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -5322,11 +5211,9 @@ type Xml struct { func (x *Xml) Reset() { *x = Xml{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[59] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[59] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Xml) String() string { @@ -5337,7 +5224,7 @@ func (*Xml) ProtoMessage() {} func (x *Xml) ProtoReflect() protoreflect.Message { mi := &file_openapiv2_OpenAPIv2_proto_msgTypes[59] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -6356,7 +6243,7 @@ func file_openapiv2_OpenAPIv2_proto_rawDescGZIP() []byte { } var file_openapiv2_OpenAPIv2_proto_msgTypes = make([]protoimpl.MessageInfo, 60) -var file_openapiv2_OpenAPIv2_proto_goTypes = []interface{}{ +var file_openapiv2_OpenAPIv2_proto_goTypes = []any{ (*AdditionalPropertiesItem)(nil), // 0: openapi.v2.AdditionalPropertiesItem (*Any)(nil), // 1: openapi.v2.Any (*ApiKeySecurity)(nil), // 2: openapi.v2.ApiKeySecurity @@ -6565,755 +6452,33 @@ func file_openapiv2_OpenAPIv2_proto_init() { if File_openapiv2_OpenAPIv2_proto != nil { return } - if !protoimpl.UnsafeEnabled { - file_openapiv2_OpenAPIv2_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AdditionalPropertiesItem); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Any); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ApiKeySecurity); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BasicAuthenticationSecurity); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BodyParameter); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Contact); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Default); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Definitions); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Document); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Examples); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ExternalDocs); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FileSchema); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FormDataParameterSubSchema); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Header); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HeaderParameterSubSchema); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Headers); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Info); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ItemsItem); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*JsonReference); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*License); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NamedAny); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NamedHeader); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NamedParameter); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NamedPathItem); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NamedResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NamedResponseValue); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NamedSchema); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NamedSecurityDefinitionsItem); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NamedString); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NamedStringArray); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NonBodyParameter); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Oauth2AccessCodeSecurity); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Oauth2ApplicationSecurity); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Oauth2ImplicitSecurity); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Oauth2PasswordSecurity); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Oauth2Scopes); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Operation); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Parameter); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ParameterDefinitions); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ParametersItem); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PathItem); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PathParameterSubSchema); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Paths); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PrimitivesItems); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Properties); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*QueryParameterSubSchema); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Response); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ResponseDefinitions); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ResponseValue); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[49].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Responses); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[50].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Schema); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[51].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SchemaItem); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[52].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SecurityDefinitions); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[53].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SecurityDefinitionsItem); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[54].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SecurityRequirement); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[55].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*StringArray); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[56].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Tag); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[57].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TypeItem); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[58].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VendorExtension); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[59].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Xml); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_openapiv2_OpenAPIv2_proto_msgTypes[0].OneofWrappers = []interface{}{ + file_openapiv2_OpenAPIv2_proto_msgTypes[0].OneofWrappers = []any{ (*AdditionalPropertiesItem_Schema)(nil), (*AdditionalPropertiesItem_Boolean)(nil), } - file_openapiv2_OpenAPIv2_proto_msgTypes[30].OneofWrappers = []interface{}{ + file_openapiv2_OpenAPIv2_proto_msgTypes[30].OneofWrappers = []any{ (*NonBodyParameter_HeaderParameterSubSchema)(nil), (*NonBodyParameter_FormDataParameterSubSchema)(nil), (*NonBodyParameter_QueryParameterSubSchema)(nil), (*NonBodyParameter_PathParameterSubSchema)(nil), } - file_openapiv2_OpenAPIv2_proto_msgTypes[37].OneofWrappers = []interface{}{ + file_openapiv2_OpenAPIv2_proto_msgTypes[37].OneofWrappers = []any{ (*Parameter_BodyParameter)(nil), (*Parameter_NonBodyParameter)(nil), } - file_openapiv2_OpenAPIv2_proto_msgTypes[39].OneofWrappers = []interface{}{ + file_openapiv2_OpenAPIv2_proto_msgTypes[39].OneofWrappers = []any{ (*ParametersItem_Parameter)(nil), (*ParametersItem_JsonReference)(nil), } - file_openapiv2_OpenAPIv2_proto_msgTypes[48].OneofWrappers = []interface{}{ + file_openapiv2_OpenAPIv2_proto_msgTypes[48].OneofWrappers = []any{ (*ResponseValue_Response)(nil), (*ResponseValue_JsonReference)(nil), } - file_openapiv2_OpenAPIv2_proto_msgTypes[51].OneofWrappers = []interface{}{ + file_openapiv2_OpenAPIv2_proto_msgTypes[51].OneofWrappers = []any{ (*SchemaItem_Schema)(nil), (*SchemaItem_FileSchema)(nil), } - file_openapiv2_OpenAPIv2_proto_msgTypes[53].OneofWrappers = []interface{}{ + file_openapiv2_OpenAPIv2_proto_msgTypes[53].OneofWrappers = []any{ (*SecurityDefinitionsItem_BasicAuthenticationSecurity)(nil), (*SecurityDefinitionsItem_ApiKeySecurity)(nil), (*SecurityDefinitionsItem_Oauth2ImplicitSecurity)(nil), diff --git a/go-controller/vendor/github.com/google/gnostic-models/openapiv3/OpenAPIv3.pb.go b/go-controller/vendor/github.com/google/gnostic-models/openapiv3/OpenAPIv3.pb.go index 945b8d11ff..b9df95a379 100644 --- a/go-controller/vendor/github.com/google/gnostic-models/openapiv3/OpenAPIv3.pb.go +++ b/go-controller/vendor/github.com/google/gnostic-models/openapiv3/OpenAPIv3.pb.go @@ -16,8 +16,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.27.1 -// protoc v3.19.3 +// protoc-gen-go v1.35.1 +// protoc v4.23.4 // source: openapiv3/OpenAPIv3.proto package openapi_v3 @@ -43,6 +43,7 @@ type AdditionalPropertiesItem struct { unknownFields protoimpl.UnknownFields // Types that are assignable to Oneof: + // // *AdditionalPropertiesItem_SchemaOrReference // *AdditionalPropertiesItem_Boolean Oneof isAdditionalPropertiesItem_Oneof `protobuf_oneof:"oneof"` @@ -50,11 +51,9 @@ type AdditionalPropertiesItem struct { func (x *AdditionalPropertiesItem) Reset() { *x = AdditionalPropertiesItem{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *AdditionalPropertiesItem) String() string { @@ -65,7 +64,7 @@ func (*AdditionalPropertiesItem) ProtoMessage() {} func (x *AdditionalPropertiesItem) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -128,11 +127,9 @@ type Any struct { func (x *Any) Reset() { *x = Any{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Any) String() string { @@ -143,7 +140,7 @@ func (*Any) ProtoMessage() {} func (x *Any) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -178,6 +175,7 @@ type AnyOrExpression struct { unknownFields protoimpl.UnknownFields // Types that are assignable to Oneof: + // // *AnyOrExpression_Any // *AnyOrExpression_Expression Oneof isAnyOrExpression_Oneof `protobuf_oneof:"oneof"` @@ -185,11 +183,9 @@ type AnyOrExpression struct { func (x *AnyOrExpression) Reset() { *x = AnyOrExpression{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *AnyOrExpression) String() string { @@ -200,7 +196,7 @@ func (*AnyOrExpression) ProtoMessage() {} func (x *AnyOrExpression) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -264,11 +260,9 @@ type Callback struct { func (x *Callback) Reset() { *x = Callback{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Callback) String() string { @@ -279,7 +273,7 @@ func (*Callback) ProtoMessage() {} func (x *Callback) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -314,6 +308,7 @@ type CallbackOrReference struct { unknownFields protoimpl.UnknownFields // Types that are assignable to Oneof: + // // *CallbackOrReference_Callback // *CallbackOrReference_Reference Oneof isCallbackOrReference_Oneof `protobuf_oneof:"oneof"` @@ -321,11 +316,9 @@ type CallbackOrReference struct { func (x *CallbackOrReference) Reset() { *x = CallbackOrReference{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *CallbackOrReference) String() string { @@ -336,7 +329,7 @@ func (*CallbackOrReference) ProtoMessage() {} func (x *CallbackOrReference) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -398,11 +391,9 @@ type CallbacksOrReferences struct { func (x *CallbacksOrReferences) Reset() { *x = CallbacksOrReferences{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *CallbacksOrReferences) String() string { @@ -413,7 +404,7 @@ func (*CallbacksOrReferences) ProtoMessage() {} func (x *CallbacksOrReferences) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -455,11 +446,9 @@ type Components struct { func (x *Components) Reset() { *x = Components{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Components) String() string { @@ -470,7 +459,7 @@ func (*Components) ProtoMessage() {} func (x *Components) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -569,11 +558,9 @@ type Contact struct { func (x *Contact) Reset() { *x = Contact{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Contact) String() string { @@ -584,7 +571,7 @@ func (*Contact) ProtoMessage() {} func (x *Contact) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -633,6 +620,7 @@ type DefaultType struct { unknownFields protoimpl.UnknownFields // Types that are assignable to Oneof: + // // *DefaultType_Number // *DefaultType_Boolean // *DefaultType_String_ @@ -641,11 +629,9 @@ type DefaultType struct { func (x *DefaultType) Reset() { *x = DefaultType{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *DefaultType) String() string { @@ -656,7 +642,7 @@ func (*DefaultType) ProtoMessage() {} func (x *DefaultType) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -734,11 +720,9 @@ type Discriminator struct { func (x *Discriminator) Reset() { *x = Discriminator{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Discriminator) String() string { @@ -749,7 +733,7 @@ func (*Discriminator) ProtoMessage() {} func (x *Discriminator) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -803,11 +787,9 @@ type Document struct { func (x *Document) Reset() { *x = Document{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Document) String() string { @@ -818,7 +800,7 @@ func (*Document) ProtoMessage() {} func (x *Document) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -912,11 +894,9 @@ type Encoding struct { func (x *Encoding) Reset() { *x = Encoding{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Encoding) String() string { @@ -927,7 +907,7 @@ func (*Encoding) ProtoMessage() {} func (x *Encoding) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -994,11 +974,9 @@ type Encodings struct { func (x *Encodings) Reset() { *x = Encodings{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Encodings) String() string { @@ -1009,7 +987,7 @@ func (*Encodings) ProtoMessage() {} func (x *Encodings) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1045,11 +1023,9 @@ type Example struct { func (x *Example) Reset() { *x = Example{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Example) String() string { @@ -1060,7 +1036,7 @@ func (*Example) ProtoMessage() {} func (x *Example) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[13] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1116,6 +1092,7 @@ type ExampleOrReference struct { unknownFields protoimpl.UnknownFields // Types that are assignable to Oneof: + // // *ExampleOrReference_Example // *ExampleOrReference_Reference Oneof isExampleOrReference_Oneof `protobuf_oneof:"oneof"` @@ -1123,11 +1100,9 @@ type ExampleOrReference struct { func (x *ExampleOrReference) Reset() { *x = ExampleOrReference{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ExampleOrReference) String() string { @@ -1138,7 +1113,7 @@ func (*ExampleOrReference) ProtoMessage() {} func (x *ExampleOrReference) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[14] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1200,11 +1175,9 @@ type ExamplesOrReferences struct { func (x *ExamplesOrReferences) Reset() { *x = ExamplesOrReferences{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[15] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ExamplesOrReferences) String() string { @@ -1215,7 +1188,7 @@ func (*ExamplesOrReferences) ProtoMessage() {} func (x *ExamplesOrReferences) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[15] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1247,11 +1220,9 @@ type Expression struct { func (x *Expression) Reset() { *x = Expression{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[16] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Expression) String() string { @@ -1262,7 +1233,7 @@ func (*Expression) ProtoMessage() {} func (x *Expression) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[16] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1297,11 +1268,9 @@ type ExternalDocs struct { func (x *ExternalDocs) Reset() { *x = ExternalDocs{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[17] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ExternalDocs) String() string { @@ -1312,7 +1281,7 @@ func (*ExternalDocs) ProtoMessage() {} func (x *ExternalDocs) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[17] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1370,11 +1339,9 @@ type Header struct { func (x *Header) Reset() { *x = Header{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[18] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Header) String() string { @@ -1385,7 +1352,7 @@ func (*Header) ProtoMessage() {} func (x *Header) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[18] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1490,6 +1457,7 @@ type HeaderOrReference struct { unknownFields protoimpl.UnknownFields // Types that are assignable to Oneof: + // // *HeaderOrReference_Header // *HeaderOrReference_Reference Oneof isHeaderOrReference_Oneof `protobuf_oneof:"oneof"` @@ -1497,11 +1465,9 @@ type HeaderOrReference struct { func (x *HeaderOrReference) Reset() { *x = HeaderOrReference{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[19] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *HeaderOrReference) String() string { @@ -1512,7 +1478,7 @@ func (*HeaderOrReference) ProtoMessage() {} func (x *HeaderOrReference) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[19] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1574,11 +1540,9 @@ type HeadersOrReferences struct { func (x *HeadersOrReferences) Reset() { *x = HeadersOrReferences{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[20] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *HeadersOrReferences) String() string { @@ -1589,7 +1553,7 @@ func (*HeadersOrReferences) ProtoMessage() {} func (x *HeadersOrReferences) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[20] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1629,11 +1593,9 @@ type Info struct { func (x *Info) Reset() { *x = Info{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[21] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Info) String() string { @@ -1644,7 +1606,7 @@ func (*Info) ProtoMessage() {} func (x *Info) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[21] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1725,11 +1687,9 @@ type ItemsItem struct { func (x *ItemsItem) Reset() { *x = ItemsItem{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[22] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ItemsItem) String() string { @@ -1740,7 +1700,7 @@ func (*ItemsItem) ProtoMessage() {} func (x *ItemsItem) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[22] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1775,11 +1735,9 @@ type License struct { func (x *License) Reset() { *x = License{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[23] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *License) String() string { @@ -1790,7 +1748,7 @@ func (*License) ProtoMessage() {} func (x *License) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[23] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1843,11 +1801,9 @@ type Link struct { func (x *Link) Reset() { *x = Link{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[24] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Link) String() string { @@ -1858,7 +1814,7 @@ func (*Link) ProtoMessage() {} func (x *Link) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[24] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1928,6 +1884,7 @@ type LinkOrReference struct { unknownFields protoimpl.UnknownFields // Types that are assignable to Oneof: + // // *LinkOrReference_Link // *LinkOrReference_Reference Oneof isLinkOrReference_Oneof `protobuf_oneof:"oneof"` @@ -1935,11 +1892,9 @@ type LinkOrReference struct { func (x *LinkOrReference) Reset() { *x = LinkOrReference{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[25] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *LinkOrReference) String() string { @@ -1950,7 +1905,7 @@ func (*LinkOrReference) ProtoMessage() {} func (x *LinkOrReference) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[25] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2012,11 +1967,9 @@ type LinksOrReferences struct { func (x *LinksOrReferences) Reset() { *x = LinksOrReferences{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[26] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *LinksOrReferences) String() string { @@ -2027,7 +1980,7 @@ func (*LinksOrReferences) ProtoMessage() {} func (x *LinksOrReferences) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[26] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2064,11 +2017,9 @@ type MediaType struct { func (x *MediaType) Reset() { *x = MediaType{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[27] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *MediaType) String() string { @@ -2079,7 +2030,7 @@ func (*MediaType) ProtoMessage() {} func (x *MediaType) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[27] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2139,11 +2090,9 @@ type MediaTypes struct { func (x *MediaTypes) Reset() { *x = MediaTypes{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[28] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *MediaTypes) String() string { @@ -2154,7 +2103,7 @@ func (*MediaTypes) ProtoMessage() {} func (x *MediaTypes) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[28] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2190,11 +2139,9 @@ type NamedAny struct { func (x *NamedAny) Reset() { *x = NamedAny{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[29] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *NamedAny) String() string { @@ -2205,7 +2152,7 @@ func (*NamedAny) ProtoMessage() {} func (x *NamedAny) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[29] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2248,11 +2195,9 @@ type NamedCallbackOrReference struct { func (x *NamedCallbackOrReference) Reset() { *x = NamedCallbackOrReference{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[30] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *NamedCallbackOrReference) String() string { @@ -2263,7 +2208,7 @@ func (*NamedCallbackOrReference) ProtoMessage() {} func (x *NamedCallbackOrReference) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[30] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2306,11 +2251,9 @@ type NamedEncoding struct { func (x *NamedEncoding) Reset() { *x = NamedEncoding{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[31] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[31] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *NamedEncoding) String() string { @@ -2321,7 +2264,7 @@ func (*NamedEncoding) ProtoMessage() {} func (x *NamedEncoding) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[31] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2364,11 +2307,9 @@ type NamedExampleOrReference struct { func (x *NamedExampleOrReference) Reset() { *x = NamedExampleOrReference{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[32] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[32] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *NamedExampleOrReference) String() string { @@ -2379,7 +2320,7 @@ func (*NamedExampleOrReference) ProtoMessage() {} func (x *NamedExampleOrReference) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[32] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2422,11 +2363,9 @@ type NamedHeaderOrReference struct { func (x *NamedHeaderOrReference) Reset() { *x = NamedHeaderOrReference{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[33] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[33] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *NamedHeaderOrReference) String() string { @@ -2437,7 +2376,7 @@ func (*NamedHeaderOrReference) ProtoMessage() {} func (x *NamedHeaderOrReference) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[33] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2480,11 +2419,9 @@ type NamedLinkOrReference struct { func (x *NamedLinkOrReference) Reset() { *x = NamedLinkOrReference{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[34] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[34] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *NamedLinkOrReference) String() string { @@ -2495,7 +2432,7 @@ func (*NamedLinkOrReference) ProtoMessage() {} func (x *NamedLinkOrReference) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[34] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2538,11 +2475,9 @@ type NamedMediaType struct { func (x *NamedMediaType) Reset() { *x = NamedMediaType{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[35] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[35] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *NamedMediaType) String() string { @@ -2553,7 +2488,7 @@ func (*NamedMediaType) ProtoMessage() {} func (x *NamedMediaType) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[35] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2596,11 +2531,9 @@ type NamedParameterOrReference struct { func (x *NamedParameterOrReference) Reset() { *x = NamedParameterOrReference{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[36] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[36] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *NamedParameterOrReference) String() string { @@ -2611,7 +2544,7 @@ func (*NamedParameterOrReference) ProtoMessage() {} func (x *NamedParameterOrReference) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[36] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2654,11 +2587,9 @@ type NamedPathItem struct { func (x *NamedPathItem) Reset() { *x = NamedPathItem{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[37] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[37] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *NamedPathItem) String() string { @@ -2669,7 +2600,7 @@ func (*NamedPathItem) ProtoMessage() {} func (x *NamedPathItem) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[37] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2712,11 +2643,9 @@ type NamedRequestBodyOrReference struct { func (x *NamedRequestBodyOrReference) Reset() { *x = NamedRequestBodyOrReference{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[38] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[38] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *NamedRequestBodyOrReference) String() string { @@ -2727,7 +2656,7 @@ func (*NamedRequestBodyOrReference) ProtoMessage() {} func (x *NamedRequestBodyOrReference) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[38] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2770,11 +2699,9 @@ type NamedResponseOrReference struct { func (x *NamedResponseOrReference) Reset() { *x = NamedResponseOrReference{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[39] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[39] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *NamedResponseOrReference) String() string { @@ -2785,7 +2712,7 @@ func (*NamedResponseOrReference) ProtoMessage() {} func (x *NamedResponseOrReference) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[39] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2828,11 +2755,9 @@ type NamedSchemaOrReference struct { func (x *NamedSchemaOrReference) Reset() { *x = NamedSchemaOrReference{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[40] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[40] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *NamedSchemaOrReference) String() string { @@ -2843,7 +2768,7 @@ func (*NamedSchemaOrReference) ProtoMessage() {} func (x *NamedSchemaOrReference) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[40] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2886,11 +2811,9 @@ type NamedSecuritySchemeOrReference struct { func (x *NamedSecuritySchemeOrReference) Reset() { *x = NamedSecuritySchemeOrReference{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[41] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[41] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *NamedSecuritySchemeOrReference) String() string { @@ -2901,7 +2824,7 @@ func (*NamedSecuritySchemeOrReference) ProtoMessage() {} func (x *NamedSecuritySchemeOrReference) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[41] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2944,11 +2867,9 @@ type NamedServerVariable struct { func (x *NamedServerVariable) Reset() { *x = NamedServerVariable{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[42] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[42] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *NamedServerVariable) String() string { @@ -2959,7 +2880,7 @@ func (*NamedServerVariable) ProtoMessage() {} func (x *NamedServerVariable) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[42] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3002,11 +2923,9 @@ type NamedString struct { func (x *NamedString) Reset() { *x = NamedString{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[43] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[43] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *NamedString) String() string { @@ -3017,7 +2936,7 @@ func (*NamedString) ProtoMessage() {} func (x *NamedString) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[43] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3060,11 +2979,9 @@ type NamedStringArray struct { func (x *NamedStringArray) Reset() { *x = NamedStringArray{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[44] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[44] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *NamedStringArray) String() string { @@ -3075,7 +2992,7 @@ func (*NamedStringArray) ProtoMessage() {} func (x *NamedStringArray) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[44] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3119,11 +3036,9 @@ type OauthFlow struct { func (x *OauthFlow) Reset() { *x = OauthFlow{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[45] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[45] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *OauthFlow) String() string { @@ -3134,7 +3049,7 @@ func (*OauthFlow) ProtoMessage() {} func (x *OauthFlow) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[45] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3199,11 +3114,9 @@ type OauthFlows struct { func (x *OauthFlows) Reset() { *x = OauthFlows{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[46] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[46] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *OauthFlows) String() string { @@ -3214,7 +3127,7 @@ func (*OauthFlows) ProtoMessage() {} func (x *OauthFlows) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[46] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3274,11 +3187,9 @@ type Object struct { func (x *Object) Reset() { *x = Object{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[47] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[47] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Object) String() string { @@ -3289,7 +3200,7 @@ func (*Object) ProtoMessage() {} func (x *Object) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[47] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3334,11 +3245,9 @@ type Operation struct { func (x *Operation) Reset() { *x = Operation{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[48] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[48] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Operation) String() string { @@ -3349,7 +3258,7 @@ func (*Operation) ProtoMessage() {} func (x *Operation) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[48] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3479,11 +3388,9 @@ type Parameter struct { func (x *Parameter) Reset() { *x = Parameter{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[49] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[49] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Parameter) String() string { @@ -3494,7 +3401,7 @@ func (*Parameter) ProtoMessage() {} func (x *Parameter) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[49] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3613,6 +3520,7 @@ type ParameterOrReference struct { unknownFields protoimpl.UnknownFields // Types that are assignable to Oneof: + // // *ParameterOrReference_Parameter // *ParameterOrReference_Reference Oneof isParameterOrReference_Oneof `protobuf_oneof:"oneof"` @@ -3620,11 +3528,9 @@ type ParameterOrReference struct { func (x *ParameterOrReference) Reset() { *x = ParameterOrReference{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[50] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[50] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ParameterOrReference) String() string { @@ -3635,7 +3541,7 @@ func (*ParameterOrReference) ProtoMessage() {} func (x *ParameterOrReference) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[50] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3697,11 +3603,9 @@ type ParametersOrReferences struct { func (x *ParametersOrReferences) Reset() { *x = ParametersOrReferences{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[51] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[51] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ParametersOrReferences) String() string { @@ -3712,7 +3616,7 @@ func (*ParametersOrReferences) ProtoMessage() {} func (x *ParametersOrReferences) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[51] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3758,11 +3662,9 @@ type PathItem struct { func (x *PathItem) Reset() { *x = PathItem{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[52] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[52] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *PathItem) String() string { @@ -3773,7 +3675,7 @@ func (*PathItem) ProtoMessage() {} func (x *PathItem) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[52] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3898,11 +3800,9 @@ type Paths struct { func (x *Paths) Reset() { *x = Paths{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[53] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[53] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Paths) String() string { @@ -3913,7 +3813,7 @@ func (*Paths) ProtoMessage() {} func (x *Paths) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[53] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3952,11 +3852,9 @@ type Properties struct { func (x *Properties) Reset() { *x = Properties{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[54] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[54] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Properties) String() string { @@ -3967,7 +3865,7 @@ func (*Properties) ProtoMessage() {} func (x *Properties) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[54] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4002,11 +3900,9 @@ type Reference struct { func (x *Reference) Reset() { *x = Reference{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[55] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[55] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Reference) String() string { @@ -4017,7 +3913,7 @@ func (*Reference) ProtoMessage() {} func (x *Reference) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[55] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4063,11 +3959,9 @@ type RequestBodiesOrReferences struct { func (x *RequestBodiesOrReferences) Reset() { *x = RequestBodiesOrReferences{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[56] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[56] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *RequestBodiesOrReferences) String() string { @@ -4078,7 +3972,7 @@ func (*RequestBodiesOrReferences) ProtoMessage() {} func (x *RequestBodiesOrReferences) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[56] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4114,11 +4008,9 @@ type RequestBody struct { func (x *RequestBody) Reset() { *x = RequestBody{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[57] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[57] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *RequestBody) String() string { @@ -4129,7 +4021,7 @@ func (*RequestBody) ProtoMessage() {} func (x *RequestBody) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[57] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4178,6 +4070,7 @@ type RequestBodyOrReference struct { unknownFields protoimpl.UnknownFields // Types that are assignable to Oneof: + // // *RequestBodyOrReference_RequestBody // *RequestBodyOrReference_Reference Oneof isRequestBodyOrReference_Oneof `protobuf_oneof:"oneof"` @@ -4185,11 +4078,9 @@ type RequestBodyOrReference struct { func (x *RequestBodyOrReference) Reset() { *x = RequestBodyOrReference{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[58] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[58] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *RequestBodyOrReference) String() string { @@ -4200,7 +4091,7 @@ func (*RequestBodyOrReference) ProtoMessage() {} func (x *RequestBodyOrReference) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[58] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4267,11 +4158,9 @@ type Response struct { func (x *Response) Reset() { *x = Response{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[59] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[59] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Response) String() string { @@ -4282,7 +4171,7 @@ func (*Response) ProtoMessage() {} func (x *Response) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[59] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4338,6 +4227,7 @@ type ResponseOrReference struct { unknownFields protoimpl.UnknownFields // Types that are assignable to Oneof: + // // *ResponseOrReference_Response // *ResponseOrReference_Reference Oneof isResponseOrReference_Oneof `protobuf_oneof:"oneof"` @@ -4345,11 +4235,9 @@ type ResponseOrReference struct { func (x *ResponseOrReference) Reset() { *x = ResponseOrReference{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[60] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[60] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ResponseOrReference) String() string { @@ -4360,7 +4248,7 @@ func (*ResponseOrReference) ProtoMessage() {} func (x *ResponseOrReference) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[60] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4425,11 +4313,9 @@ type Responses struct { func (x *Responses) Reset() { *x = Responses{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[61] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[61] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Responses) String() string { @@ -4440,7 +4326,7 @@ func (*Responses) ProtoMessage() {} func (x *Responses) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[61] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4486,11 +4372,9 @@ type ResponsesOrReferences struct { func (x *ResponsesOrReferences) Reset() { *x = ResponsesOrReferences{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[62] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[62] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ResponsesOrReferences) String() string { @@ -4501,7 +4385,7 @@ func (*ResponsesOrReferences) ProtoMessage() {} func (x *ResponsesOrReferences) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[62] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4569,11 +4453,9 @@ type Schema struct { func (x *Schema) Reset() { *x = Schema{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[63] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[63] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Schema) String() string { @@ -4584,7 +4466,7 @@ func (*Schema) ProtoMessage() {} func (x *Schema) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[63] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4857,6 +4739,7 @@ type SchemaOrReference struct { unknownFields protoimpl.UnknownFields // Types that are assignable to Oneof: + // // *SchemaOrReference_Schema // *SchemaOrReference_Reference Oneof isSchemaOrReference_Oneof `protobuf_oneof:"oneof"` @@ -4864,11 +4747,9 @@ type SchemaOrReference struct { func (x *SchemaOrReference) Reset() { *x = SchemaOrReference{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[64] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[64] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SchemaOrReference) String() string { @@ -4879,7 +4760,7 @@ func (*SchemaOrReference) ProtoMessage() {} func (x *SchemaOrReference) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[64] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4941,11 +4822,9 @@ type SchemasOrReferences struct { func (x *SchemasOrReferences) Reset() { *x = SchemasOrReferences{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[65] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[65] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SchemasOrReferences) String() string { @@ -4956,7 +4835,7 @@ func (*SchemasOrReferences) ProtoMessage() {} func (x *SchemasOrReferences) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[65] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4989,11 +4868,9 @@ type SecurityRequirement struct { func (x *SecurityRequirement) Reset() { *x = SecurityRequirement{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[66] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[66] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SecurityRequirement) String() string { @@ -5004,7 +4881,7 @@ func (*SecurityRequirement) ProtoMessage() {} func (x *SecurityRequirement) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[66] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -5045,11 +4922,9 @@ type SecurityScheme struct { func (x *SecurityScheme) Reset() { *x = SecurityScheme{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[67] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[67] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SecurityScheme) String() string { @@ -5060,7 +4935,7 @@ func (*SecurityScheme) ProtoMessage() {} func (x *SecurityScheme) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[67] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -5144,6 +5019,7 @@ type SecuritySchemeOrReference struct { unknownFields protoimpl.UnknownFields // Types that are assignable to Oneof: + // // *SecuritySchemeOrReference_SecurityScheme // *SecuritySchemeOrReference_Reference Oneof isSecuritySchemeOrReference_Oneof `protobuf_oneof:"oneof"` @@ -5151,11 +5027,9 @@ type SecuritySchemeOrReference struct { func (x *SecuritySchemeOrReference) Reset() { *x = SecuritySchemeOrReference{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[68] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[68] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SecuritySchemeOrReference) String() string { @@ -5166,7 +5040,7 @@ func (*SecuritySchemeOrReference) ProtoMessage() {} func (x *SecuritySchemeOrReference) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[68] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -5228,11 +5102,9 @@ type SecuritySchemesOrReferences struct { func (x *SecuritySchemesOrReferences) Reset() { *x = SecuritySchemesOrReferences{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[69] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[69] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SecuritySchemesOrReferences) String() string { @@ -5243,7 +5115,7 @@ func (*SecuritySchemesOrReferences) ProtoMessage() {} func (x *SecuritySchemesOrReferences) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[69] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -5279,11 +5151,9 @@ type Server struct { func (x *Server) Reset() { *x = Server{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[70] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[70] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Server) String() string { @@ -5294,7 +5164,7 @@ func (*Server) ProtoMessage() {} func (x *Server) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[70] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -5351,11 +5221,9 @@ type ServerVariable struct { func (x *ServerVariable) Reset() { *x = ServerVariable{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[71] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[71] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ServerVariable) String() string { @@ -5366,7 +5234,7 @@ func (*ServerVariable) ProtoMessage() {} func (x *ServerVariable) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[71] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -5419,11 +5287,9 @@ type ServerVariables struct { func (x *ServerVariables) Reset() { *x = ServerVariables{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[72] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[72] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ServerVariables) String() string { @@ -5434,7 +5300,7 @@ func (*ServerVariables) ProtoMessage() {} func (x *ServerVariables) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[72] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -5463,6 +5329,7 @@ type SpecificationExtension struct { unknownFields protoimpl.UnknownFields // Types that are assignable to Oneof: + // // *SpecificationExtension_Number // *SpecificationExtension_Boolean // *SpecificationExtension_String_ @@ -5471,11 +5338,9 @@ type SpecificationExtension struct { func (x *SpecificationExtension) Reset() { *x = SpecificationExtension{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[73] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[73] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SpecificationExtension) String() string { @@ -5486,7 +5351,7 @@ func (*SpecificationExtension) ProtoMessage() {} func (x *SpecificationExtension) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[73] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -5561,11 +5426,9 @@ type StringArray struct { func (x *StringArray) Reset() { *x = StringArray{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[74] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[74] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *StringArray) String() string { @@ -5576,7 +5439,7 @@ func (*StringArray) ProtoMessage() {} func (x *StringArray) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[74] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -5608,11 +5471,9 @@ type Strings struct { func (x *Strings) Reset() { *x = Strings{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[75] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[75] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Strings) String() string { @@ -5623,7 +5484,7 @@ func (*Strings) ProtoMessage() {} func (x *Strings) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[75] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -5659,11 +5520,9 @@ type Tag struct { func (x *Tag) Reset() { *x = Tag{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[76] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[76] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Tag) String() string { @@ -5674,7 +5533,7 @@ func (*Tag) ProtoMessage() {} func (x *Tag) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[76] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -5733,11 +5592,9 @@ type Xml struct { func (x *Xml) Reset() { *x = Xml{} - if protoimpl.UnsafeEnabled { - mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[77] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[77] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Xml) String() string { @@ -5748,7 +5605,7 @@ func (*Xml) ProtoMessage() {} func (x *Xml) ProtoReflect() protoreflect.Message { mi := &file_openapiv3_OpenAPIv3_proto_msgTypes[77] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -6781,7 +6638,7 @@ func file_openapiv3_OpenAPIv3_proto_rawDescGZIP() []byte { } var file_openapiv3_OpenAPIv3_proto_msgTypes = make([]protoimpl.MessageInfo, 78) -var file_openapiv3_OpenAPIv3_proto_goTypes = []interface{}{ +var file_openapiv3_OpenAPIv3_proto_goTypes = []any{ (*AdditionalPropertiesItem)(nil), // 0: openapi.v3.AdditionalPropertiesItem (*Any)(nil), // 1: openapi.v3.Any (*AnyOrExpression)(nil), // 2: openapi.v3.AnyOrExpression @@ -7040,994 +6897,56 @@ func file_openapiv3_OpenAPIv3_proto_init() { if File_openapiv3_OpenAPIv3_proto != nil { return } - if !protoimpl.UnsafeEnabled { - file_openapiv3_OpenAPIv3_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AdditionalPropertiesItem); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Any); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AnyOrExpression); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Callback); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CallbackOrReference); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CallbacksOrReferences); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Components); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Contact); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DefaultType); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Discriminator); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Document); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Encoding); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Encodings); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Example); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ExampleOrReference); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ExamplesOrReferences); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Expression); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ExternalDocs); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Header); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HeaderOrReference); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HeadersOrReferences); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Info); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ItemsItem); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*License); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Link); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*LinkOrReference); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*LinksOrReferences); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MediaType); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MediaTypes); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NamedAny); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NamedCallbackOrReference); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NamedEncoding); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NamedExampleOrReference); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NamedHeaderOrReference); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NamedLinkOrReference); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NamedMediaType); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NamedParameterOrReference); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NamedPathItem); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NamedRequestBodyOrReference); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NamedResponseOrReference); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NamedSchemaOrReference); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NamedSecuritySchemeOrReference); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NamedServerVariable); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NamedString); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NamedStringArray); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*OauthFlow); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*OauthFlows); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Object); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Operation); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[49].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Parameter); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[50].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ParameterOrReference); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[51].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ParametersOrReferences); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[52].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PathItem); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[53].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Paths); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[54].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Properties); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[55].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Reference); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[56].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RequestBodiesOrReferences); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[57].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RequestBody); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[58].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RequestBodyOrReference); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[59].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Response); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[60].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ResponseOrReference); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[61].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Responses); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[62].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ResponsesOrReferences); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[63].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Schema); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[64].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SchemaOrReference); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[65].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SchemasOrReferences); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[66].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SecurityRequirement); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[67].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SecurityScheme); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[68].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SecuritySchemeOrReference); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[69].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SecuritySchemesOrReferences); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[70].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Server); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[71].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ServerVariable); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[72].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ServerVariables); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[73].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SpecificationExtension); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[74].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*StringArray); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[75].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Strings); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[76].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Tag); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[77].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Xml); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_openapiv3_OpenAPIv3_proto_msgTypes[0].OneofWrappers = []interface{}{ + file_openapiv3_OpenAPIv3_proto_msgTypes[0].OneofWrappers = []any{ (*AdditionalPropertiesItem_SchemaOrReference)(nil), (*AdditionalPropertiesItem_Boolean)(nil), } - file_openapiv3_OpenAPIv3_proto_msgTypes[2].OneofWrappers = []interface{}{ + file_openapiv3_OpenAPIv3_proto_msgTypes[2].OneofWrappers = []any{ (*AnyOrExpression_Any)(nil), (*AnyOrExpression_Expression)(nil), } - file_openapiv3_OpenAPIv3_proto_msgTypes[4].OneofWrappers = []interface{}{ + file_openapiv3_OpenAPIv3_proto_msgTypes[4].OneofWrappers = []any{ (*CallbackOrReference_Callback)(nil), (*CallbackOrReference_Reference)(nil), } - file_openapiv3_OpenAPIv3_proto_msgTypes[8].OneofWrappers = []interface{}{ + file_openapiv3_OpenAPIv3_proto_msgTypes[8].OneofWrappers = []any{ (*DefaultType_Number)(nil), (*DefaultType_Boolean)(nil), (*DefaultType_String_)(nil), } - file_openapiv3_OpenAPIv3_proto_msgTypes[14].OneofWrappers = []interface{}{ + file_openapiv3_OpenAPIv3_proto_msgTypes[14].OneofWrappers = []any{ (*ExampleOrReference_Example)(nil), (*ExampleOrReference_Reference)(nil), } - file_openapiv3_OpenAPIv3_proto_msgTypes[19].OneofWrappers = []interface{}{ + file_openapiv3_OpenAPIv3_proto_msgTypes[19].OneofWrappers = []any{ (*HeaderOrReference_Header)(nil), (*HeaderOrReference_Reference)(nil), } - file_openapiv3_OpenAPIv3_proto_msgTypes[25].OneofWrappers = []interface{}{ + file_openapiv3_OpenAPIv3_proto_msgTypes[25].OneofWrappers = []any{ (*LinkOrReference_Link)(nil), (*LinkOrReference_Reference)(nil), } - file_openapiv3_OpenAPIv3_proto_msgTypes[50].OneofWrappers = []interface{}{ + file_openapiv3_OpenAPIv3_proto_msgTypes[50].OneofWrappers = []any{ (*ParameterOrReference_Parameter)(nil), (*ParameterOrReference_Reference)(nil), } - file_openapiv3_OpenAPIv3_proto_msgTypes[58].OneofWrappers = []interface{}{ + file_openapiv3_OpenAPIv3_proto_msgTypes[58].OneofWrappers = []any{ (*RequestBodyOrReference_RequestBody)(nil), (*RequestBodyOrReference_Reference)(nil), } - file_openapiv3_OpenAPIv3_proto_msgTypes[60].OneofWrappers = []interface{}{ + file_openapiv3_OpenAPIv3_proto_msgTypes[60].OneofWrappers = []any{ (*ResponseOrReference_Response)(nil), (*ResponseOrReference_Reference)(nil), } - file_openapiv3_OpenAPIv3_proto_msgTypes[64].OneofWrappers = []interface{}{ + file_openapiv3_OpenAPIv3_proto_msgTypes[64].OneofWrappers = []any{ (*SchemaOrReference_Schema)(nil), (*SchemaOrReference_Reference)(nil), } - file_openapiv3_OpenAPIv3_proto_msgTypes[68].OneofWrappers = []interface{}{ + file_openapiv3_OpenAPIv3_proto_msgTypes[68].OneofWrappers = []any{ (*SecuritySchemeOrReference_SecurityScheme)(nil), (*SecuritySchemeOrReference_Reference)(nil), } - file_openapiv3_OpenAPIv3_proto_msgTypes[73].OneofWrappers = []interface{}{ + file_openapiv3_OpenAPIv3_proto_msgTypes[73].OneofWrappers = []any{ (*SpecificationExtension_Number)(nil), (*SpecificationExtension_Boolean)(nil), (*SpecificationExtension_String_)(nil), diff --git a/go-controller/vendor/github.com/google/gnostic-models/openapiv3/annotations.pb.go b/go-controller/vendor/github.com/google/gnostic-models/openapiv3/annotations.pb.go new file mode 100644 index 0000000000..f9f1bd2654 --- /dev/null +++ b/go-controller/vendor/github.com/google/gnostic-models/openapiv3/annotations.pb.go @@ -0,0 +1,182 @@ +// Copyright 2022 Google LLC. All Rights Reserved. +// +// 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. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc v4.23.4 +// source: openapiv3/annotations.proto + +package openapi_v3 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + descriptorpb "google.golang.org/protobuf/types/descriptorpb" + reflect "reflect" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +var file_openapiv3_annotations_proto_extTypes = []protoimpl.ExtensionInfo{ + { + ExtendedType: (*descriptorpb.FileOptions)(nil), + ExtensionType: (*Document)(nil), + Field: 1143, + Name: "openapi.v3.document", + Tag: "bytes,1143,opt,name=document", + Filename: "openapiv3/annotations.proto", + }, + { + ExtendedType: (*descriptorpb.MethodOptions)(nil), + ExtensionType: (*Operation)(nil), + Field: 1143, + Name: "openapi.v3.operation", + Tag: "bytes,1143,opt,name=operation", + Filename: "openapiv3/annotations.proto", + }, + { + ExtendedType: (*descriptorpb.MessageOptions)(nil), + ExtensionType: (*Schema)(nil), + Field: 1143, + Name: "openapi.v3.schema", + Tag: "bytes,1143,opt,name=schema", + Filename: "openapiv3/annotations.proto", + }, + { + ExtendedType: (*descriptorpb.FieldOptions)(nil), + ExtensionType: (*Schema)(nil), + Field: 1143, + Name: "openapi.v3.property", + Tag: "bytes,1143,opt,name=property", + Filename: "openapiv3/annotations.proto", + }, +} + +// Extension fields to descriptorpb.FileOptions. +var ( + // optional openapi.v3.Document document = 1143; + E_Document = &file_openapiv3_annotations_proto_extTypes[0] +) + +// Extension fields to descriptorpb.MethodOptions. +var ( + // optional openapi.v3.Operation operation = 1143; + E_Operation = &file_openapiv3_annotations_proto_extTypes[1] +) + +// Extension fields to descriptorpb.MessageOptions. +var ( + // optional openapi.v3.Schema schema = 1143; + E_Schema = &file_openapiv3_annotations_proto_extTypes[2] +) + +// Extension fields to descriptorpb.FieldOptions. +var ( + // optional openapi.v3.Schema property = 1143; + E_Property = &file_openapiv3_annotations_proto_extTypes[3] +) + +var File_openapiv3_annotations_proto protoreflect.FileDescriptor + +var file_openapiv3_annotations_proto_rawDesc = []byte{ + 0x0a, 0x1b, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x33, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x6f, + 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x6f, 0x70, 0x65, + 0x6e, 0x61, 0x70, 0x69, 0x76, 0x33, 0x2f, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x50, 0x49, 0x76, 0x33, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3a, 0x4f, 0x0a, 0x08, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0xf7, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, + 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x08, 0x64, + 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x3a, 0x54, 0x0a, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xf7, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6f, 0x70, + 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x4c, 0x0a, + 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xf7, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x12, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x3a, 0x4e, 0x0a, 0x08, 0x70, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x12, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xf7, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, + 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, + 0x61, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x42, 0x42, 0x0a, 0x0e, 0x6f, + 0x72, 0x67, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x5f, 0x76, 0x33, 0x42, 0x10, 0x41, + 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, + 0x01, 0x5a, 0x16, 0x2e, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x33, 0x3b, 0x6f, + 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x5f, 0x76, 0x33, 0xa2, 0x02, 0x03, 0x4f, 0x41, 0x53, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var file_openapiv3_annotations_proto_goTypes = []any{ + (*descriptorpb.FileOptions)(nil), // 0: google.protobuf.FileOptions + (*descriptorpb.MethodOptions)(nil), // 1: google.protobuf.MethodOptions + (*descriptorpb.MessageOptions)(nil), // 2: google.protobuf.MessageOptions + (*descriptorpb.FieldOptions)(nil), // 3: google.protobuf.FieldOptions + (*Document)(nil), // 4: openapi.v3.Document + (*Operation)(nil), // 5: openapi.v3.Operation + (*Schema)(nil), // 6: openapi.v3.Schema +} +var file_openapiv3_annotations_proto_depIdxs = []int32{ + 0, // 0: openapi.v3.document:extendee -> google.protobuf.FileOptions + 1, // 1: openapi.v3.operation:extendee -> google.protobuf.MethodOptions + 2, // 2: openapi.v3.schema:extendee -> google.protobuf.MessageOptions + 3, // 3: openapi.v3.property:extendee -> google.protobuf.FieldOptions + 4, // 4: openapi.v3.document:type_name -> openapi.v3.Document + 5, // 5: openapi.v3.operation:type_name -> openapi.v3.Operation + 6, // 6: openapi.v3.schema:type_name -> openapi.v3.Schema + 6, // 7: openapi.v3.property:type_name -> openapi.v3.Schema + 8, // [8:8] is the sub-list for method output_type + 8, // [8:8] is the sub-list for method input_type + 4, // [4:8] is the sub-list for extension type_name + 0, // [0:4] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_openapiv3_annotations_proto_init() } +func file_openapiv3_annotations_proto_init() { + if File_openapiv3_annotations_proto != nil { + return + } + file_openapiv3_OpenAPIv3_proto_init() + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_openapiv3_annotations_proto_rawDesc, + NumEnums: 0, + NumMessages: 0, + NumExtensions: 4, + NumServices: 0, + }, + GoTypes: file_openapiv3_annotations_proto_goTypes, + DependencyIndexes: file_openapiv3_annotations_proto_depIdxs, + ExtensionInfos: file_openapiv3_annotations_proto_extTypes, + }.Build() + File_openapiv3_annotations_proto = out.File + file_openapiv3_annotations_proto_rawDesc = nil + file_openapiv3_annotations_proto_goTypes = nil + file_openapiv3_annotations_proto_depIdxs = nil +} diff --git a/go-controller/vendor/github.com/google/gnostic-models/openapiv3/annotations.proto b/go-controller/vendor/github.com/google/gnostic-models/openapiv3/annotations.proto new file mode 100644 index 0000000000..09ee0aac51 --- /dev/null +++ b/go-controller/vendor/github.com/google/gnostic-models/openapiv3/annotations.proto @@ -0,0 +1,56 @@ +// Copyright 2022 Google LLC. All Rights Reserved. +// +// 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. + +syntax = "proto3"; + +package openapi.v3; + +import "google/protobuf/descriptor.proto"; +import "openapiv3/OpenAPIv3.proto"; + +// The Go package name. +option go_package = "./openapiv3;openapi_v3"; +// This option lets the proto compiler generate Java code inside the package +// name (see below) instead of inside an outer class. It creates a simpler +// developer experience by reducing one-level of name nesting and be +// consistent with most programming languages that don't support outer classes. +option java_multiple_files = true; +// The Java outer classname should be the filename in UpperCamelCase. This +// class is only used to hold proto descriptor, so developers don't need to +// work with it directly. +option java_outer_classname = "AnnotationsProto"; +// The Java package name must be proto package name with proper prefix. +option java_package = "org.openapi_v3"; +// A reasonable prefix for the Objective-C symbols generated from the package. +// It should at a minimum be 3 characters long, all uppercase, and convention +// is to use an abbreviation of the package name. Something short, but +// hopefully unique enough to not conflict with things that may come along in +// the future. 'GPB' is reserved for the protocol buffer implementation itself. +option objc_class_prefix = "OAS"; + +extend google.protobuf.FileOptions { + Document document = 1143; +} + +extend google.protobuf.MethodOptions { + Operation operation = 1143; +} + +extend google.protobuf.MessageOptions { + Schema schema = 1143; +} + +extend google.protobuf.FieldOptions { + Schema property = 1143; +} diff --git a/go-controller/vendor/github.com/google/go-cmp/cmp/cmpopts/sort.go b/go-controller/vendor/github.com/google/go-cmp/cmp/cmpopts/sort.go index c6d09dae40..720f3cdf57 100644 --- a/go-controller/vendor/github.com/google/go-cmp/cmp/cmpopts/sort.go +++ b/go-controller/vendor/github.com/google/go-cmp/cmp/cmpopts/sort.go @@ -14,22 +14,29 @@ import ( ) // SortSlices returns a [cmp.Transformer] option that sorts all []V. -// The less function must be of the form "func(T, T) bool" which is used to -// sort any slice with element type V that is assignable to T. +// The lessOrCompareFunc function must be either +// a less function of the form "func(T, T) bool" or +// a compare function of the format "func(T, T) int" +// which is used to sort any slice with element type V that is assignable to T. // -// The less function must be: +// A less function must be: // - Deterministic: less(x, y) == less(x, y) // - Irreflexive: !less(x, x) // - Transitive: if !less(x, y) and !less(y, z), then !less(x, z) // -// The less function does not have to be "total". That is, if !less(x, y) and -// !less(y, x) for two elements x and y, their relative order is maintained. +// A compare function must be: +// - Deterministic: compare(x, y) == compare(x, y) +// - Irreflexive: compare(x, x) == 0 +// - Transitive: if !less(x, y) and !less(y, z), then !less(x, z) +// +// The function does not have to be "total". That is, if x != y, but +// less or compare report inequality, their relative order is maintained. // // SortSlices can be used in conjunction with [EquateEmpty]. -func SortSlices(lessFunc interface{}) cmp.Option { - vf := reflect.ValueOf(lessFunc) - if !function.IsType(vf.Type(), function.Less) || vf.IsNil() { - panic(fmt.Sprintf("invalid less function: %T", lessFunc)) +func SortSlices(lessOrCompareFunc interface{}) cmp.Option { + vf := reflect.ValueOf(lessOrCompareFunc) + if (!function.IsType(vf.Type(), function.Less) && !function.IsType(vf.Type(), function.Compare)) || vf.IsNil() { + panic(fmt.Sprintf("invalid less or compare function: %T", lessOrCompareFunc)) } ss := sliceSorter{vf.Type().In(0), vf} return cmp.FilterValues(ss.filter, cmp.Transformer("cmpopts.SortSlices", ss.sort)) @@ -79,28 +86,40 @@ func (ss sliceSorter) checkSort(v reflect.Value) { } func (ss sliceSorter) less(v reflect.Value, i, j int) bool { vx, vy := v.Index(i), v.Index(j) - return ss.fnc.Call([]reflect.Value{vx, vy})[0].Bool() + vo := ss.fnc.Call([]reflect.Value{vx, vy})[0] + if vo.Kind() == reflect.Bool { + return vo.Bool() + } else { + return vo.Int() < 0 + } } -// SortMaps returns a [cmp.Transformer] option that flattens map[K]V types to be a -// sorted []struct{K, V}. The less function must be of the form -// "func(T, T) bool" which is used to sort any map with key K that is -// assignable to T. +// SortMaps returns a [cmp.Transformer] option that flattens map[K]V types to be +// a sorted []struct{K, V}. The lessOrCompareFunc function must be either +// a less function of the form "func(T, T) bool" or +// a compare function of the format "func(T, T) int" +// which is used to sort any map with key K that is assignable to T. // // Flattening the map into a slice has the property that [cmp.Equal] is able to // use [cmp.Comparer] options on K or the K.Equal method if it exists. // -// The less function must be: +// A less function must be: // - Deterministic: less(x, y) == less(x, y) // - Irreflexive: !less(x, x) // - Transitive: if !less(x, y) and !less(y, z), then !less(x, z) // - Total: if x != y, then either less(x, y) or less(y, x) // +// A compare function must be: +// - Deterministic: compare(x, y) == compare(x, y) +// - Irreflexive: compare(x, x) == 0 +// - Transitive: if compare(x, y) < 0 and compare(y, z) < 0, then compare(x, z) < 0 +// - Total: if x != y, then compare(x, y) != 0 +// // SortMaps can be used in conjunction with [EquateEmpty]. -func SortMaps(lessFunc interface{}) cmp.Option { - vf := reflect.ValueOf(lessFunc) - if !function.IsType(vf.Type(), function.Less) || vf.IsNil() { - panic(fmt.Sprintf("invalid less function: %T", lessFunc)) +func SortMaps(lessOrCompareFunc interface{}) cmp.Option { + vf := reflect.ValueOf(lessOrCompareFunc) + if (!function.IsType(vf.Type(), function.Less) && !function.IsType(vf.Type(), function.Compare)) || vf.IsNil() { + panic(fmt.Sprintf("invalid less or compare function: %T", lessOrCompareFunc)) } ms := mapSorter{vf.Type().In(0), vf} return cmp.FilterValues(ms.filter, cmp.Transformer("cmpopts.SortMaps", ms.sort)) @@ -143,5 +162,10 @@ func (ms mapSorter) checkSort(v reflect.Value) { } func (ms mapSorter) less(v reflect.Value, i, j int) bool { vx, vy := v.Index(i).Field(0), v.Index(j).Field(0) - return ms.fnc.Call([]reflect.Value{vx, vy})[0].Bool() + vo := ms.fnc.Call([]reflect.Value{vx, vy})[0] + if vo.Kind() == reflect.Bool { + return vo.Bool() + } else { + return vo.Int() < 0 + } } diff --git a/go-controller/vendor/github.com/google/go-cmp/cmp/internal/function/func.go b/go-controller/vendor/github.com/google/go-cmp/cmp/internal/function/func.go index d127d43623..def01a6be3 100644 --- a/go-controller/vendor/github.com/google/go-cmp/cmp/internal/function/func.go +++ b/go-controller/vendor/github.com/google/go-cmp/cmp/internal/function/func.go @@ -19,6 +19,7 @@ const ( tbFunc // func(T) bool ttbFunc // func(T, T) bool + ttiFunc // func(T, T) int trbFunc // func(T, R) bool tibFunc // func(T, I) bool trFunc // func(T) R @@ -28,11 +29,13 @@ const ( Transformer = trFunc // func(T) R ValueFilter = ttbFunc // func(T, T) bool Less = ttbFunc // func(T, T) bool + Compare = ttiFunc // func(T, T) int ValuePredicate = tbFunc // func(T) bool KeyValuePredicate = trbFunc // func(T, R) bool ) var boolType = reflect.TypeOf(true) +var intType = reflect.TypeOf(0) // IsType reports whether the reflect.Type is of the specified function type. func IsType(t reflect.Type, ft funcType) bool { @@ -49,6 +52,10 @@ func IsType(t reflect.Type, ft funcType) bool { if ni == 2 && no == 1 && t.In(0) == t.In(1) && t.Out(0) == boolType { return true } + case ttiFunc: // func(T, T) int + if ni == 2 && no == 1 && t.In(0) == t.In(1) && t.Out(0) == intType { + return true + } case trbFunc: // func(T, R) bool if ni == 2 && no == 1 && t.Out(0) == boolType { return true diff --git a/go-controller/vendor/github.com/google/go-cmp/cmp/options.go b/go-controller/vendor/github.com/google/go-cmp/cmp/options.go index 754496f3b3..ba3fce81ff 100644 --- a/go-controller/vendor/github.com/google/go-cmp/cmp/options.go +++ b/go-controller/vendor/github.com/google/go-cmp/cmp/options.go @@ -232,7 +232,15 @@ func (validator) apply(s *state, vx, vy reflect.Value) { if t := s.curPath.Index(-2).Type(); t.Name() != "" { // Named type with unexported fields. name = fmt.Sprintf("%q.%v", t.PkgPath(), t.Name()) // e.g., "path/to/package".MyType - if _, ok := reflect.New(t).Interface().(error); ok { + isProtoMessage := func(t reflect.Type) bool { + m, ok := reflect.PointerTo(t).MethodByName("ProtoReflect") + return ok && m.Type.NumIn() == 1 && m.Type.NumOut() == 1 && + m.Type.Out(0).PkgPath() == "google.golang.org/protobuf/reflect/protoreflect" && + m.Type.Out(0).Name() == "Message" + } + if isProtoMessage(t) { + help = `consider using "google.golang.org/protobuf/testing/protocmp".Transform to compare proto.Message types` + } else if _, ok := reflect.New(t).Interface().(error); ok { help = "consider using cmpopts.EquateErrors to compare error values" } else if t.Comparable() { help = "consider using cmpopts.EquateComparable to compare comparable Go types" diff --git a/go-controller/vendor/github.com/google/gofuzz/.travis.yml b/go-controller/vendor/github.com/google/gofuzz/.travis.yml deleted file mode 100644 index 061d72ae07..0000000000 --- a/go-controller/vendor/github.com/google/gofuzz/.travis.yml +++ /dev/null @@ -1,10 +0,0 @@ -language: go - -go: - - 1.11.x - - 1.12.x - - 1.13.x - - master - -script: - - go test -cover diff --git a/go-controller/vendor/github.com/google/gofuzz/CONTRIBUTING.md b/go-controller/vendor/github.com/google/gofuzz/CONTRIBUTING.md deleted file mode 100644 index 97c1b34fd5..0000000000 --- a/go-controller/vendor/github.com/google/gofuzz/CONTRIBUTING.md +++ /dev/null @@ -1,67 +0,0 @@ -# How to contribute # - -We'd love to accept your patches and contributions to this project. There are -just a few small guidelines you need to follow. - - -## Contributor License Agreement ## - -Contributions to any Google project must be accompanied by a Contributor -License Agreement. This is not a copyright **assignment**, it simply gives -Google permission to use and redistribute your contributions as part of the -project. - - * If you are an individual writing original source code and you're sure you - own the intellectual property, then you'll need to sign an [individual - CLA][]. - - * If you work for a company that wants to allow you to contribute your work, - then you'll need to sign a [corporate CLA][]. - -You generally only need to submit a CLA once, so if you've already submitted -one (even if it was for a different project), you probably don't need to do it -again. - -[individual CLA]: https://developers.google.com/open-source/cla/individual -[corporate CLA]: https://developers.google.com/open-source/cla/corporate - - -## Submitting a patch ## - - 1. It's generally best to start by opening a new issue describing the bug or - feature you're intending to fix. Even if you think it's relatively minor, - it's helpful to know what people are working on. Mention in the initial - issue that you are planning to work on that bug or feature so that it can - be assigned to you. - - 1. Follow the normal process of [forking][] the project, and setup a new - branch to work in. It's important that each group of changes be done in - separate branches in order to ensure that a pull request only includes the - commits related to that bug or feature. - - 1. Go makes it very simple to ensure properly formatted code, so always run - `go fmt` on your code before committing it. You should also run - [golint][] over your code. As noted in the [golint readme][], it's not - strictly necessary that your code be completely "lint-free", but this will - help you find common style issues. - - 1. Any significant changes should almost always be accompanied by tests. The - project already has good test coverage, so look at some of the existing - tests if you're unsure how to go about it. [gocov][] and [gocov-html][] - are invaluable tools for seeing which parts of your code aren't being - exercised by your tests. - - 1. Do your best to have [well-formed commit messages][] for each change. - This provides consistency throughout the project, and ensures that commit - messages are able to be formatted properly by various git tools. - - 1. Finally, push the commits to your fork and submit a [pull request][]. - -[forking]: https://help.github.com/articles/fork-a-repo -[golint]: https://github.com/golang/lint -[golint readme]: https://github.com/golang/lint/blob/master/README -[gocov]: https://github.com/axw/gocov -[gocov-html]: https://github.com/matm/gocov-html -[well-formed commit messages]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html -[squash]: http://git-scm.com/book/en/Git-Tools-Rewriting-History#Squashing-Commits -[pull request]: https://help.github.com/articles/creating-a-pull-request diff --git a/go-controller/vendor/github.com/google/gofuzz/fuzz.go b/go-controller/vendor/github.com/google/gofuzz/fuzz.go deleted file mode 100644 index 761520a8ce..0000000000 --- a/go-controller/vendor/github.com/google/gofuzz/fuzz.go +++ /dev/null @@ -1,605 +0,0 @@ -/* -Copyright 2014 Google Inc. All rights reserved. - -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 fuzz - -import ( - "fmt" - "math/rand" - "reflect" - "regexp" - "time" - - "github.com/google/gofuzz/bytesource" - "strings" -) - -// fuzzFuncMap is a map from a type to a fuzzFunc that handles that type. -type fuzzFuncMap map[reflect.Type]reflect.Value - -// Fuzzer knows how to fill any object with random fields. -type Fuzzer struct { - fuzzFuncs fuzzFuncMap - defaultFuzzFuncs fuzzFuncMap - r *rand.Rand - nilChance float64 - minElements int - maxElements int - maxDepth int - skipFieldPatterns []*regexp.Regexp -} - -// New returns a new Fuzzer. Customize your Fuzzer further by calling Funcs, -// RandSource, NilChance, or NumElements in any order. -func New() *Fuzzer { - return NewWithSeed(time.Now().UnixNano()) -} - -func NewWithSeed(seed int64) *Fuzzer { - f := &Fuzzer{ - defaultFuzzFuncs: fuzzFuncMap{ - reflect.TypeOf(&time.Time{}): reflect.ValueOf(fuzzTime), - }, - - fuzzFuncs: fuzzFuncMap{}, - r: rand.New(rand.NewSource(seed)), - nilChance: .2, - minElements: 1, - maxElements: 10, - maxDepth: 100, - } - return f -} - -// NewFromGoFuzz is a helper function that enables using gofuzz (this -// project) with go-fuzz (https://github.com/dvyukov/go-fuzz) for continuous -// fuzzing. Essentially, it enables translating the fuzzing bytes from -// go-fuzz to any Go object using this library. -// -// This implementation promises a constant translation from a given slice of -// bytes to the fuzzed objects. This promise will remain over future -// versions of Go and of this library. -// -// Note: the returned Fuzzer should not be shared between multiple goroutines, -// as its deterministic output will no longer be available. -// -// Example: use go-fuzz to test the function `MyFunc(int)` in the package -// `mypackage`. Add the file: "mypacakge_fuzz.go" with the content: -// -// // +build gofuzz -// package mypacakge -// import fuzz "github.com/google/gofuzz" -// func Fuzz(data []byte) int { -// var i int -// fuzz.NewFromGoFuzz(data).Fuzz(&i) -// MyFunc(i) -// return 0 -// } -func NewFromGoFuzz(data []byte) *Fuzzer { - return New().RandSource(bytesource.New(data)) -} - -// Funcs adds each entry in fuzzFuncs as a custom fuzzing function. -// -// Each entry in fuzzFuncs must be a function taking two parameters. -// The first parameter must be a pointer or map. It is the variable that -// function will fill with random data. The second parameter must be a -// fuzz.Continue, which will provide a source of randomness and a way -// to automatically continue fuzzing smaller pieces of the first parameter. -// -// These functions are called sensibly, e.g., if you wanted custom string -// fuzzing, the function `func(s *string, c fuzz.Continue)` would get -// called and passed the address of strings. Maps and pointers will always -// be made/new'd for you, ignoring the NilChange option. For slices, it -// doesn't make much sense to pre-create them--Fuzzer doesn't know how -// long you want your slice--so take a pointer to a slice, and make it -// yourself. (If you don't want your map/pointer type pre-made, take a -// pointer to it, and make it yourself.) See the examples for a range of -// custom functions. -func (f *Fuzzer) Funcs(fuzzFuncs ...interface{}) *Fuzzer { - for i := range fuzzFuncs { - v := reflect.ValueOf(fuzzFuncs[i]) - if v.Kind() != reflect.Func { - panic("Need only funcs!") - } - t := v.Type() - if t.NumIn() != 2 || t.NumOut() != 0 { - panic("Need 2 in and 0 out params!") - } - argT := t.In(0) - switch argT.Kind() { - case reflect.Ptr, reflect.Map: - default: - panic("fuzzFunc must take pointer or map type") - } - if t.In(1) != reflect.TypeOf(Continue{}) { - panic("fuzzFunc's second parameter must be type fuzz.Continue") - } - f.fuzzFuncs[argT] = v - } - return f -} - -// RandSource causes f to get values from the given source of randomness. -// Use if you want deterministic fuzzing. -func (f *Fuzzer) RandSource(s rand.Source) *Fuzzer { - f.r = rand.New(s) - return f -} - -// NilChance sets the probability of creating a nil pointer, map, or slice to -// 'p'. 'p' should be between 0 (no nils) and 1 (all nils), inclusive. -func (f *Fuzzer) NilChance(p float64) *Fuzzer { - if p < 0 || p > 1 { - panic("p should be between 0 and 1, inclusive.") - } - f.nilChance = p - return f -} - -// NumElements sets the minimum and maximum number of elements that will be -// added to a non-nil map or slice. -func (f *Fuzzer) NumElements(atLeast, atMost int) *Fuzzer { - if atLeast > atMost { - panic("atLeast must be <= atMost") - } - if atLeast < 0 { - panic("atLeast must be >= 0") - } - f.minElements = atLeast - f.maxElements = atMost - return f -} - -func (f *Fuzzer) genElementCount() int { - if f.minElements == f.maxElements { - return f.minElements - } - return f.minElements + f.r.Intn(f.maxElements-f.minElements+1) -} - -func (f *Fuzzer) genShouldFill() bool { - return f.r.Float64() >= f.nilChance -} - -// MaxDepth sets the maximum number of recursive fuzz calls that will be made -// before stopping. This includes struct members, pointers, and map and slice -// elements. -func (f *Fuzzer) MaxDepth(d int) *Fuzzer { - f.maxDepth = d - return f -} - -// Skip fields which match the supplied pattern. Call this multiple times if needed -// This is useful to skip XXX_ fields generated by protobuf -func (f *Fuzzer) SkipFieldsWithPattern(pattern *regexp.Regexp) *Fuzzer { - f.skipFieldPatterns = append(f.skipFieldPatterns, pattern) - return f -} - -// Fuzz recursively fills all of obj's fields with something random. First -// this tries to find a custom fuzz function (see Funcs). If there is no -// custom function this tests whether the object implements fuzz.Interface and, -// if so, calls Fuzz on it to fuzz itself. If that fails, this will see if -// there is a default fuzz function provided by this package. If all of that -// fails, this will generate random values for all primitive fields and then -// recurse for all non-primitives. -// -// This is safe for cyclic or tree-like structs, up to a limit. Use the -// MaxDepth method to adjust how deep you need it to recurse. -// -// obj must be a pointer. Only exported (public) fields can be set (thanks, -// golang :/ ) Intended for tests, so will panic on bad input or unimplemented -// fields. -func (f *Fuzzer) Fuzz(obj interface{}) { - v := reflect.ValueOf(obj) - if v.Kind() != reflect.Ptr { - panic("needed ptr!") - } - v = v.Elem() - f.fuzzWithContext(v, 0) -} - -// FuzzNoCustom is just like Fuzz, except that any custom fuzz function for -// obj's type will not be called and obj will not be tested for fuzz.Interface -// conformance. This applies only to obj and not other instances of obj's -// type. -// Not safe for cyclic or tree-like structs! -// obj must be a pointer. Only exported (public) fields can be set (thanks, golang :/ ) -// Intended for tests, so will panic on bad input or unimplemented fields. -func (f *Fuzzer) FuzzNoCustom(obj interface{}) { - v := reflect.ValueOf(obj) - if v.Kind() != reflect.Ptr { - panic("needed ptr!") - } - v = v.Elem() - f.fuzzWithContext(v, flagNoCustomFuzz) -} - -const ( - // Do not try to find a custom fuzz function. Does not apply recursively. - flagNoCustomFuzz uint64 = 1 << iota -) - -func (f *Fuzzer) fuzzWithContext(v reflect.Value, flags uint64) { - fc := &fuzzerContext{fuzzer: f} - fc.doFuzz(v, flags) -} - -// fuzzerContext carries context about a single fuzzing run, which lets Fuzzer -// be thread-safe. -type fuzzerContext struct { - fuzzer *Fuzzer - curDepth int -} - -func (fc *fuzzerContext) doFuzz(v reflect.Value, flags uint64) { - if fc.curDepth >= fc.fuzzer.maxDepth { - return - } - fc.curDepth++ - defer func() { fc.curDepth-- }() - - if !v.CanSet() { - return - } - - if flags&flagNoCustomFuzz == 0 { - // Check for both pointer and non-pointer custom functions. - if v.CanAddr() && fc.tryCustom(v.Addr()) { - return - } - if fc.tryCustom(v) { - return - } - } - - if fn, ok := fillFuncMap[v.Kind()]; ok { - fn(v, fc.fuzzer.r) - return - } - - switch v.Kind() { - case reflect.Map: - if fc.fuzzer.genShouldFill() { - v.Set(reflect.MakeMap(v.Type())) - n := fc.fuzzer.genElementCount() - for i := 0; i < n; i++ { - key := reflect.New(v.Type().Key()).Elem() - fc.doFuzz(key, 0) - val := reflect.New(v.Type().Elem()).Elem() - fc.doFuzz(val, 0) - v.SetMapIndex(key, val) - } - return - } - v.Set(reflect.Zero(v.Type())) - case reflect.Ptr: - if fc.fuzzer.genShouldFill() { - v.Set(reflect.New(v.Type().Elem())) - fc.doFuzz(v.Elem(), 0) - return - } - v.Set(reflect.Zero(v.Type())) - case reflect.Slice: - if fc.fuzzer.genShouldFill() { - n := fc.fuzzer.genElementCount() - v.Set(reflect.MakeSlice(v.Type(), n, n)) - for i := 0; i < n; i++ { - fc.doFuzz(v.Index(i), 0) - } - return - } - v.Set(reflect.Zero(v.Type())) - case reflect.Array: - if fc.fuzzer.genShouldFill() { - n := v.Len() - for i := 0; i < n; i++ { - fc.doFuzz(v.Index(i), 0) - } - return - } - v.Set(reflect.Zero(v.Type())) - case reflect.Struct: - for i := 0; i < v.NumField(); i++ { - skipField := false - fieldName := v.Type().Field(i).Name - for _, pattern := range fc.fuzzer.skipFieldPatterns { - if pattern.MatchString(fieldName) { - skipField = true - break - } - } - if !skipField { - fc.doFuzz(v.Field(i), 0) - } - } - case reflect.Chan: - fallthrough - case reflect.Func: - fallthrough - case reflect.Interface: - fallthrough - default: - panic(fmt.Sprintf("Can't handle %#v", v.Interface())) - } -} - -// tryCustom searches for custom handlers, and returns true iff it finds a match -// and successfully randomizes v. -func (fc *fuzzerContext) tryCustom(v reflect.Value) bool { - // First: see if we have a fuzz function for it. - doCustom, ok := fc.fuzzer.fuzzFuncs[v.Type()] - if !ok { - // Second: see if it can fuzz itself. - if v.CanInterface() { - intf := v.Interface() - if fuzzable, ok := intf.(Interface); ok { - fuzzable.Fuzz(Continue{fc: fc, Rand: fc.fuzzer.r}) - return true - } - } - // Finally: see if there is a default fuzz function. - doCustom, ok = fc.fuzzer.defaultFuzzFuncs[v.Type()] - if !ok { - return false - } - } - - switch v.Kind() { - case reflect.Ptr: - if v.IsNil() { - if !v.CanSet() { - return false - } - v.Set(reflect.New(v.Type().Elem())) - } - case reflect.Map: - if v.IsNil() { - if !v.CanSet() { - return false - } - v.Set(reflect.MakeMap(v.Type())) - } - default: - return false - } - - doCustom.Call([]reflect.Value{v, reflect.ValueOf(Continue{ - fc: fc, - Rand: fc.fuzzer.r, - })}) - return true -} - -// Interface represents an object that knows how to fuzz itself. Any time we -// find a type that implements this interface we will delegate the act of -// fuzzing itself. -type Interface interface { - Fuzz(c Continue) -} - -// Continue can be passed to custom fuzzing functions to allow them to use -// the correct source of randomness and to continue fuzzing their members. -type Continue struct { - fc *fuzzerContext - - // For convenience, Continue implements rand.Rand via embedding. - // Use this for generating any randomness if you want your fuzzing - // to be repeatable for a given seed. - *rand.Rand -} - -// Fuzz continues fuzzing obj. obj must be a pointer. -func (c Continue) Fuzz(obj interface{}) { - v := reflect.ValueOf(obj) - if v.Kind() != reflect.Ptr { - panic("needed ptr!") - } - v = v.Elem() - c.fc.doFuzz(v, 0) -} - -// FuzzNoCustom continues fuzzing obj, except that any custom fuzz function for -// obj's type will not be called and obj will not be tested for fuzz.Interface -// conformance. This applies only to obj and not other instances of obj's -// type. -func (c Continue) FuzzNoCustom(obj interface{}) { - v := reflect.ValueOf(obj) - if v.Kind() != reflect.Ptr { - panic("needed ptr!") - } - v = v.Elem() - c.fc.doFuzz(v, flagNoCustomFuzz) -} - -// RandString makes a random string up to 20 characters long. The returned string -// may include a variety of (valid) UTF-8 encodings. -func (c Continue) RandString() string { - return randString(c.Rand) -} - -// RandUint64 makes random 64 bit numbers. -// Weirdly, rand doesn't have a function that gives you 64 random bits. -func (c Continue) RandUint64() uint64 { - return randUint64(c.Rand) -} - -// RandBool returns true or false randomly. -func (c Continue) RandBool() bool { - return randBool(c.Rand) -} - -func fuzzInt(v reflect.Value, r *rand.Rand) { - v.SetInt(int64(randUint64(r))) -} - -func fuzzUint(v reflect.Value, r *rand.Rand) { - v.SetUint(randUint64(r)) -} - -func fuzzTime(t *time.Time, c Continue) { - var sec, nsec int64 - // Allow for about 1000 years of random time values, which keeps things - // like JSON parsing reasonably happy. - sec = c.Rand.Int63n(1000 * 365 * 24 * 60 * 60) - c.Fuzz(&nsec) - *t = time.Unix(sec, nsec) -} - -var fillFuncMap = map[reflect.Kind]func(reflect.Value, *rand.Rand){ - reflect.Bool: func(v reflect.Value, r *rand.Rand) { - v.SetBool(randBool(r)) - }, - reflect.Int: fuzzInt, - reflect.Int8: fuzzInt, - reflect.Int16: fuzzInt, - reflect.Int32: fuzzInt, - reflect.Int64: fuzzInt, - reflect.Uint: fuzzUint, - reflect.Uint8: fuzzUint, - reflect.Uint16: fuzzUint, - reflect.Uint32: fuzzUint, - reflect.Uint64: fuzzUint, - reflect.Uintptr: fuzzUint, - reflect.Float32: func(v reflect.Value, r *rand.Rand) { - v.SetFloat(float64(r.Float32())) - }, - reflect.Float64: func(v reflect.Value, r *rand.Rand) { - v.SetFloat(r.Float64()) - }, - reflect.Complex64: func(v reflect.Value, r *rand.Rand) { - v.SetComplex(complex128(complex(r.Float32(), r.Float32()))) - }, - reflect.Complex128: func(v reflect.Value, r *rand.Rand) { - v.SetComplex(complex(r.Float64(), r.Float64())) - }, - reflect.String: func(v reflect.Value, r *rand.Rand) { - v.SetString(randString(r)) - }, - reflect.UnsafePointer: func(v reflect.Value, r *rand.Rand) { - panic("unimplemented") - }, -} - -// randBool returns true or false randomly. -func randBool(r *rand.Rand) bool { - return r.Int31()&(1<<30) == 0 -} - -type int63nPicker interface { - Int63n(int64) int64 -} - -// UnicodeRange describes a sequential range of unicode characters. -// Last must be numerically greater than First. -type UnicodeRange struct { - First, Last rune -} - -// UnicodeRanges describes an arbitrary number of sequential ranges of unicode characters. -// To be useful, each range must have at least one character (First <= Last) and -// there must be at least one range. -type UnicodeRanges []UnicodeRange - -// choose returns a random unicode character from the given range, using the -// given randomness source. -func (ur UnicodeRange) choose(r int63nPicker) rune { - count := int64(ur.Last - ur.First + 1) - return ur.First + rune(r.Int63n(count)) -} - -// CustomStringFuzzFunc constructs a FuzzFunc which produces random strings. -// Each character is selected from the range ur. If there are no characters -// in the range (cr.Last < cr.First), this will panic. -func (ur UnicodeRange) CustomStringFuzzFunc() func(s *string, c Continue) { - ur.check() - return func(s *string, c Continue) { - *s = ur.randString(c.Rand) - } -} - -// check is a function that used to check whether the first of ur(UnicodeRange) -// is greater than the last one. -func (ur UnicodeRange) check() { - if ur.Last < ur.First { - panic("The last encoding must be greater than the first one.") - } -} - -// randString of UnicodeRange makes a random string up to 20 characters long. -// Each character is selected form ur(UnicodeRange). -func (ur UnicodeRange) randString(r *rand.Rand) string { - n := r.Intn(20) - sb := strings.Builder{} - sb.Grow(n) - for i := 0; i < n; i++ { - sb.WriteRune(ur.choose(r)) - } - return sb.String() -} - -// defaultUnicodeRanges sets a default unicode range when user do not set -// CustomStringFuzzFunc() but wants fuzz string. -var defaultUnicodeRanges = UnicodeRanges{ - {' ', '~'}, // ASCII characters - {'\u00a0', '\u02af'}, // Multi-byte encoded characters - {'\u4e00', '\u9fff'}, // Common CJK (even longer encodings) -} - -// CustomStringFuzzFunc constructs a FuzzFunc which produces random strings. -// Each character is selected from one of the ranges of ur(UnicodeRanges). -// Each range has an equal probability of being chosen. If there are no ranges, -// or a selected range has no characters (.Last < .First), this will panic. -// Do not modify any of the ranges in ur after calling this function. -func (ur UnicodeRanges) CustomStringFuzzFunc() func(s *string, c Continue) { - // Check unicode ranges slice is empty. - if len(ur) == 0 { - panic("UnicodeRanges is empty.") - } - // if not empty, each range should be checked. - for i := range ur { - ur[i].check() - } - return func(s *string, c Continue) { - *s = ur.randString(c.Rand) - } -} - -// randString of UnicodeRanges makes a random string up to 20 characters long. -// Each character is selected form one of the ranges of ur(UnicodeRanges), -// and each range has an equal probability of being chosen. -func (ur UnicodeRanges) randString(r *rand.Rand) string { - n := r.Intn(20) - sb := strings.Builder{} - sb.Grow(n) - for i := 0; i < n; i++ { - sb.WriteRune(ur[r.Intn(len(ur))].choose(r)) - } - return sb.String() -} - -// randString makes a random string up to 20 characters long. The returned string -// may include a variety of (valid) UTF-8 encodings. -func randString(r *rand.Rand) string { - return defaultUnicodeRanges.randString(r) -} - -// randUint64 makes random 64 bit numbers. -// Weirdly, rand doesn't have a function that gives you 64 random bits. -func randUint64(r *rand.Rand) uint64 { - return uint64(r.Uint32())<<32 | uint64(r.Uint32()) -} diff --git a/go-controller/vendor/github.com/gorilla/websocket/README.md b/go-controller/vendor/github.com/gorilla/websocket/README.md index 2517a28715..ff8bfab0b2 100644 --- a/go-controller/vendor/github.com/gorilla/websocket/README.md +++ b/go-controller/vendor/github.com/gorilla/websocket/README.md @@ -7,19 +7,13 @@ Gorilla WebSocket is a [Go](http://golang.org/) implementation of the [WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol. ---- - -⚠️ **[The Gorilla WebSocket Package is looking for a new maintainer](https://github.com/gorilla/websocket/issues/370)** - ---- - ### Documentation * [API Reference](https://pkg.go.dev/github.com/gorilla/websocket?tab=doc) -* [Chat example](https://github.com/gorilla/websocket/tree/master/examples/chat) -* [Command example](https://github.com/gorilla/websocket/tree/master/examples/command) -* [Client and server example](https://github.com/gorilla/websocket/tree/master/examples/echo) -* [File watch example](https://github.com/gorilla/websocket/tree/master/examples/filewatch) +* [Chat example](https://github.com/gorilla/websocket/tree/main/examples/chat) +* [Command example](https://github.com/gorilla/websocket/tree/main/examples/command) +* [Client and server example](https://github.com/gorilla/websocket/tree/main/examples/echo) +* [File watch example](https://github.com/gorilla/websocket/tree/main/examples/filewatch) ### Status @@ -35,5 +29,4 @@ package API is stable. The Gorilla WebSocket package passes the server tests in the [Autobahn Test Suite](https://github.com/crossbario/autobahn-testsuite) using the application in the [examples/autobahn -subdirectory](https://github.com/gorilla/websocket/tree/master/examples/autobahn). - +subdirectory](https://github.com/gorilla/websocket/tree/main/examples/autobahn). diff --git a/go-controller/vendor/github.com/gorilla/websocket/client.go b/go-controller/vendor/github.com/gorilla/websocket/client.go index 2efd83555d..00917ea341 100644 --- a/go-controller/vendor/github.com/gorilla/websocket/client.go +++ b/go-controller/vendor/github.com/gorilla/websocket/client.go @@ -9,8 +9,8 @@ import ( "context" "crypto/tls" "errors" + "fmt" "io" - "io/ioutil" "net" "net/http" "net/http/httptrace" @@ -51,18 +51,34 @@ func NewClient(netConn net.Conn, u *url.URL, requestHeader http.Header, readBufS // // It is safe to call Dialer's methods concurrently. type Dialer struct { + // The following custom dial functions can be set to establish + // connections to either the backend server or the proxy (if it + // exists). The scheme of the dialed entity (either backend or + // proxy) determines which custom dial function is selected: + // either NetDialTLSContext for HTTPS or NetDialContext/NetDial + // for HTTP. Since the "Proxy" function can determine the scheme + // dynamically, it can make sense to set multiple custom dial + // functions simultaneously. + // // NetDial specifies the dial function for creating TCP connections. If - // NetDial is nil, net.Dial is used. + // NetDial is nil, net.Dialer DialContext is used. + // If "Proxy" field is also set, this function dials the proxy--not + // the backend server. NetDial func(network, addr string) (net.Conn, error) // NetDialContext specifies the dial function for creating TCP connections. If // NetDialContext is nil, NetDial is used. + // If "Proxy" field is also set, this function dials the proxy--not + // the backend server. NetDialContext func(ctx context.Context, network, addr string) (net.Conn, error) // NetDialTLSContext specifies the dial function for creating TLS/TCP connections. If // NetDialTLSContext is nil, NetDialContext is used. // If NetDialTLSContext is set, Dial assumes the TLS handshake is done there and // TLSClientConfig is ignored. + // If "Proxy" field is also set, this function dials the proxy (and performs + // the TLS handshake with the proxy, ignoring TLSClientConfig). In this TLS proxy + // dialing case the TLSClientConfig could still be necessary for TLS to the backend server. NetDialTLSContext func(ctx context.Context, network, addr string) (net.Conn, error) // Proxy specifies a function to return a proxy for a given @@ -73,7 +89,7 @@ type Dialer struct { // TLSClientConfig specifies the TLS configuration to use with tls.Client. // If nil, the default configuration is used. - // If either NetDialTLS or NetDialTLSContext are set, Dial assumes the TLS handshake + // If NetDialTLSContext is set, Dial assumes the TLS handshake // is done there and TLSClientConfig is ignored. TLSClientConfig *tls.Config @@ -244,71 +260,16 @@ func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader h defer cancel() } - // Get network dial function. - var netDial func(network, add string) (net.Conn, error) - - switch u.Scheme { - case "http": - if d.NetDialContext != nil { - netDial = func(network, addr string) (net.Conn, error) { - return d.NetDialContext(ctx, network, addr) - } - } else if d.NetDial != nil { - netDial = d.NetDial - } - case "https": - if d.NetDialTLSContext != nil { - netDial = func(network, addr string) (net.Conn, error) { - return d.NetDialTLSContext(ctx, network, addr) - } - } else if d.NetDialContext != nil { - netDial = func(network, addr string) (net.Conn, error) { - return d.NetDialContext(ctx, network, addr) - } - } else if d.NetDial != nil { - netDial = d.NetDial - } - default: - return nil, nil, errMalformedURL - } - - if netDial == nil { - netDialer := &net.Dialer{} - netDial = func(network, addr string) (net.Conn, error) { - return netDialer.DialContext(ctx, network, addr) - } - } - - // If needed, wrap the dial function to set the connection deadline. - if deadline, ok := ctx.Deadline(); ok { - forwardDial := netDial - netDial = func(network, addr string) (net.Conn, error) { - c, err := forwardDial(network, addr) - if err != nil { - return nil, err - } - err = c.SetDeadline(deadline) - if err != nil { - c.Close() - return nil, err - } - return c, nil - } - } - - // If needed, wrap the dial function to connect through a proxy. + var proxyURL *url.URL if d.Proxy != nil { - proxyURL, err := d.Proxy(req) + proxyURL, err = d.Proxy(req) if err != nil { return nil, nil, err } - if proxyURL != nil { - dialer, err := proxy_FromURL(proxyURL, netDialerFunc(netDial)) - if err != nil { - return nil, nil, err - } - netDial = dialer.Dial - } + } + netDial, err := d.netDialFn(ctx, proxyURL, u) + if err != nil { + return nil, nil, err } hostPort, hostNoPort := hostPortNoPort(u) @@ -317,24 +278,30 @@ func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader h trace.GetConn(hostPort) } - netConn, err := netDial("tcp", hostPort) + netConn, err := netDial(ctx, "tcp", hostPort) + if err != nil { + return nil, nil, err + } if trace != nil && trace.GotConn != nil { trace.GotConn(httptrace.GotConnInfo{ Conn: netConn, }) } - if err != nil { - return nil, nil, err - } + // Close the network connection when returning an error. The variable + // netConn is set to nil before the success return at the end of the + // function. defer func() { if netConn != nil { - netConn.Close() + // It's safe to ignore the error from Close() because this code is + // only executed when returning a more important error to the + // application. + _ = netConn.Close() } }() - if u.Scheme == "https" && d.NetDialTLSContext == nil { - // If NetDialTLSContext is set, assume that the TLS handshake has already been done + // Do TLS handshake over established connection if a proxy exists. + if proxyURL != nil && u.Scheme == "https" { cfg := cloneTLSConfig(d.TLSClientConfig) if cfg.ServerName == "" { @@ -370,6 +337,17 @@ func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader h resp, err := http.ReadResponse(conn.br, req) if err != nil { + if d.TLSClientConfig != nil { + for _, proto := range d.TLSClientConfig.NextProtos { + if proto != "http/1.1" { + return nil, nil, fmt.Errorf( + "websocket: protocol %q was given but is not supported;"+ + "sharing tls.Config with net/http Transport can cause this error: %w", + proto, err, + ) + } + } + } return nil, nil, err } @@ -388,7 +366,7 @@ func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader h // debugging. buf := make([]byte, 1024) n, _ := io.ReadFull(resp.Body, buf) - resp.Body = ioutil.NopCloser(bytes.NewReader(buf[:n])) + resp.Body = io.NopCloser(bytes.NewReader(buf[:n])) return nil, resp, ErrBadHandshake } @@ -406,17 +384,134 @@ func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader h break } - resp.Body = ioutil.NopCloser(bytes.NewReader([]byte{})) + resp.Body = io.NopCloser(bytes.NewReader([]byte{})) conn.subprotocol = resp.Header.Get("Sec-Websocket-Protocol") - netConn.SetDeadline(time.Time{}) - netConn = nil // to avoid close in defer. + if err := netConn.SetDeadline(time.Time{}); err != nil { + return nil, resp, err + } + + // Success! Set netConn to nil to stop the deferred function above from + // closing the network connection. + netConn = nil + return conn, resp, nil } +// Returns the dial function to establish the connection to either the backend +// server or the proxy (if it exists). If the dialed entity is HTTPS, then the +// returned dial function *also* performs the TLS handshake to the dialed entity. +// NOTE: If a proxy exists, it is possible for a second TLS handshake to be +// necessary over the established connection. +func (d *Dialer) netDialFn(ctx context.Context, proxyURL *url.URL, backendURL *url.URL) (netDialerFunc, error) { + var netDial netDialerFunc + if proxyURL != nil { + netDial = d.netDialFromURL(proxyURL) + } else { + netDial = d.netDialFromURL(backendURL) + } + // If needed, wrap the dial function to set the connection deadline. + if deadline, ok := ctx.Deadline(); ok { + netDial = netDialWithDeadline(netDial, deadline) + } + // Proxy dialing is wrapped to implement CONNECT method and possibly proxy auth. + if proxyURL != nil { + return proxyFromURL(proxyURL, netDial) + } + return netDial, nil +} + +// Returns function to create the connection depending on the Dialer's +// custom dialing functions and the passed URL of entity connecting to. +func (d *Dialer) netDialFromURL(u *url.URL) netDialerFunc { + var netDial netDialerFunc + switch { + case d.NetDialContext != nil: + netDial = d.NetDialContext + case d.NetDial != nil: + netDial = func(ctx context.Context, net, addr string) (net.Conn, error) { + return d.NetDial(net, addr) + } + default: + netDial = (&net.Dialer{}).DialContext + } + // If dialed entity is HTTPS, then either use custom TLS dialing function (if exists) + // or wrap the previously computed "netDial" to use TLS config for handshake. + if u.Scheme == "https" { + if d.NetDialTLSContext != nil { + netDial = d.NetDialTLSContext + } else { + netDial = netDialWithTLSHandshake(netDial, d.TLSClientConfig, u) + } + } + return netDial +} + +// Returns wrapped "netDial" function, performing TLS handshake after connecting. +func netDialWithTLSHandshake(netDial netDialerFunc, tlsConfig *tls.Config, u *url.URL) netDialerFunc { + return func(ctx context.Context, unused, addr string) (net.Conn, error) { + hostPort, hostNoPort := hostPortNoPort(u) + trace := httptrace.ContextClientTrace(ctx) + if trace != nil && trace.GetConn != nil { + trace.GetConn(hostPort) + } + // Creates TCP connection to addr using passed "netDial" function. + conn, err := netDial(ctx, "tcp", addr) + if err != nil { + return nil, err + } + cfg := cloneTLSConfig(tlsConfig) + if cfg.ServerName == "" { + cfg.ServerName = hostNoPort + } + tlsConn := tls.Client(conn, cfg) + // Do the TLS handshake using TLSConfig over the wrapped connection. + if trace != nil && trace.TLSHandshakeStart != nil { + trace.TLSHandshakeStart() + } + err = doHandshake(ctx, tlsConn, cfg) + if trace != nil && trace.TLSHandshakeDone != nil { + trace.TLSHandshakeDone(tlsConn.ConnectionState(), err) + } + if err != nil { + tlsConn.Close() + return nil, err + } + return tlsConn, nil + } +} + +// Returns wrapped "netDial" function, setting passed deadline. +func netDialWithDeadline(netDial netDialerFunc, deadline time.Time) netDialerFunc { + return func(ctx context.Context, network, addr string) (net.Conn, error) { + c, err := netDial(ctx, network, addr) + if err != nil { + return nil, err + } + err = c.SetDeadline(deadline) + if err != nil { + c.Close() + return nil, err + } + return c, nil + } +} + func cloneTLSConfig(cfg *tls.Config) *tls.Config { if cfg == nil { return &tls.Config{} } return cfg.Clone() } + +func doHandshake(ctx context.Context, tlsConn *tls.Conn, cfg *tls.Config) error { + if err := tlsConn.HandshakeContext(ctx); err != nil { + return err + } + if !cfg.InsecureSkipVerify { + if err := tlsConn.VerifyHostname(cfg.ServerName); err != nil { + return err + } + } + return nil +} diff --git a/go-controller/vendor/github.com/gorilla/websocket/compression.go b/go-controller/vendor/github.com/gorilla/websocket/compression.go index 813ffb1e84..fe1079edbc 100644 --- a/go-controller/vendor/github.com/gorilla/websocket/compression.go +++ b/go-controller/vendor/github.com/gorilla/websocket/compression.go @@ -33,7 +33,11 @@ func decompressNoContextTakeover(r io.Reader) io.ReadCloser { "\x01\x00\x00\xff\xff" fr, _ := flateReaderPool.Get().(io.ReadCloser) - fr.(flate.Resetter).Reset(io.MultiReader(r, strings.NewReader(tail)), nil) + mr := io.MultiReader(r, strings.NewReader(tail)) + if err := fr.(flate.Resetter).Reset(mr, nil); err != nil { + // Reset never fails, but handle error in case that changes. + fr = flate.NewReader(mr) + } return &flateReadWrapper{fr} } diff --git a/go-controller/vendor/github.com/gorilla/websocket/conn.go b/go-controller/vendor/github.com/gorilla/websocket/conn.go index 331eebc850..9562ffd497 100644 --- a/go-controller/vendor/github.com/gorilla/websocket/conn.go +++ b/go-controller/vendor/github.com/gorilla/websocket/conn.go @@ -6,11 +6,10 @@ package websocket import ( "bufio" + "crypto/rand" "encoding/binary" "errors" "io" - "io/ioutil" - "math/rand" "net" "strconv" "strings" @@ -181,16 +180,16 @@ var ( errInvalidControlFrame = errors.New("websocket: invalid control frame") ) -func newMaskKey() [4]byte { - n := rand.Uint32() - return [4]byte{byte(n), byte(n >> 8), byte(n >> 16), byte(n >> 24)} -} +// maskRand is an io.Reader for generating mask bytes. The reader is initialized +// to crypto/rand Reader. Tests swap the reader to a math/rand reader for +// reproducible results. +var maskRand = rand.Reader -func hideTempErr(err error) error { - if e, ok := err.(net.Error); ok && e.Temporary() { - err = &netError{msg: e.Error(), timeout: e.Timeout()} - } - return err +// newMaskKey returns a new 32 bit value for masking client frames. +func newMaskKey() [4]byte { + var k [4]byte + _, _ = io.ReadFull(maskRand, k[:]) + return k } func isControl(frameType int) bool { @@ -358,7 +357,6 @@ func (c *Conn) RemoteAddr() net.Addr { // Write methods func (c *Conn) writeFatal(err error) error { - err = hideTempErr(err) c.writeErrMu.Lock() if c.writeErr == nil { c.writeErr = err @@ -372,7 +370,9 @@ func (c *Conn) read(n int) ([]byte, error) { if err == io.EOF { err = errUnexpectedEOF } - c.br.Discard(len(p)) + // Discard is guaranteed to succeed because the number of bytes to discard + // is less than or equal to the number of bytes buffered. + _, _ = c.br.Discard(len(p)) return p, err } @@ -387,7 +387,9 @@ func (c *Conn) write(frameType int, deadline time.Time, buf0, buf1 []byte) error return err } - c.conn.SetWriteDeadline(deadline) + if err := c.conn.SetWriteDeadline(deadline); err != nil { + return c.writeFatal(err) + } if len(buf1) == 0 { _, err = c.conn.Write(buf0) } else { @@ -397,7 +399,7 @@ func (c *Conn) write(frameType int, deadline time.Time, buf0, buf1 []byte) error return c.writeFatal(err) } if frameType == CloseMessage { - c.writeFatal(ErrCloseSent) + _ = c.writeFatal(ErrCloseSent) } return nil } @@ -436,21 +438,27 @@ func (c *Conn) WriteControl(messageType int, data []byte, deadline time.Time) er maskBytes(key, 0, buf[6:]) } - d := 1000 * time.Hour - if !deadline.IsZero() { - d = deadline.Sub(time.Now()) + if deadline.IsZero() { + // No timeout for zero time. + <-c.mu + } else { + d := time.Until(deadline) if d < 0 { return errWriteTimeout } + select { + case <-c.mu: + default: + timer := time.NewTimer(d) + select { + case <-c.mu: + timer.Stop() + case <-timer.C: + return errWriteTimeout + } + } } - timer := time.NewTimer(d) - select { - case <-c.mu: - timer.Stop() - case <-timer.C: - return errWriteTimeout - } defer func() { c.mu <- struct{}{} }() c.writeErrMu.Lock() @@ -460,13 +468,14 @@ func (c *Conn) WriteControl(messageType int, data []byte, deadline time.Time) er return err } - c.conn.SetWriteDeadline(deadline) - _, err = c.conn.Write(buf) - if err != nil { + if err := c.conn.SetWriteDeadline(deadline); err != nil { + return c.writeFatal(err) + } + if _, err = c.conn.Write(buf); err != nil { return c.writeFatal(err) } if messageType == CloseMessage { - c.writeFatal(ErrCloseSent) + _ = c.writeFatal(ErrCloseSent) } return err } @@ -630,7 +639,7 @@ func (w *messageWriter) flushFrame(final bool, extra []byte) error { } if final { - w.endMessage(errWriteClosed) + _ = w.endMessage(errWriteClosed) return nil } @@ -795,7 +804,7 @@ func (c *Conn) advanceFrame() (int, error) { // 1. Skip remainder of previous frame. if c.readRemaining > 0 { - if _, err := io.CopyN(ioutil.Discard, c.br, c.readRemaining); err != nil { + if _, err := io.CopyN(io.Discard, c.br, c.readRemaining); err != nil { return noFrame, err } } @@ -817,7 +826,7 @@ func (c *Conn) advanceFrame() (int, error) { rsv2 := p[0]&rsv2Bit != 0 rsv3 := p[0]&rsv3Bit != 0 mask := p[1]&maskBit != 0 - c.setReadRemaining(int64(p[1] & 0x7f)) + _ = c.setReadRemaining(int64(p[1] & 0x7f)) // will not fail because argument is >= 0 c.readDecompress = false if rsv1 { @@ -922,7 +931,8 @@ func (c *Conn) advanceFrame() (int, error) { } if c.readLimit > 0 && c.readLength > c.readLimit { - c.WriteControl(CloseMessage, FormatCloseMessage(CloseMessageTooBig, ""), time.Now().Add(writeWait)) + // Make a best effort to send a close message describing the problem. + _ = c.WriteControl(CloseMessage, FormatCloseMessage(CloseMessageTooBig, ""), time.Now().Add(writeWait)) return noFrame, ErrReadLimit } @@ -934,7 +944,7 @@ func (c *Conn) advanceFrame() (int, error) { var payload []byte if c.readRemaining > 0 { payload, err = c.read(int(c.readRemaining)) - c.setReadRemaining(0) + _ = c.setReadRemaining(0) // will not fail because argument is >= 0 if err != nil { return noFrame, err } @@ -981,7 +991,8 @@ func (c *Conn) handleProtocolError(message string) error { if len(data) > maxControlFramePayloadSize { data = data[:maxControlFramePayloadSize] } - c.WriteControl(CloseMessage, data, time.Now().Add(writeWait)) + // Make a best effor to send a close message describing the problem. + _ = c.WriteControl(CloseMessage, data, time.Now().Add(writeWait)) return errors.New("websocket: " + message) } @@ -1008,7 +1019,7 @@ func (c *Conn) NextReader() (messageType int, r io.Reader, err error) { for c.readErr == nil { frameType, err := c.advanceFrame() if err != nil { - c.readErr = hideTempErr(err) + c.readErr = err break } @@ -1048,13 +1059,13 @@ func (r *messageReader) Read(b []byte) (int, error) { b = b[:c.readRemaining] } n, err := c.br.Read(b) - c.readErr = hideTempErr(err) + c.readErr = err if c.isServer { c.readMaskPos = maskBytes(c.readMaskKey, c.readMaskPos, b[:n]) } rem := c.readRemaining rem -= int64(n) - c.setReadRemaining(rem) + _ = c.setReadRemaining(rem) // rem is guaranteed to be >= 0 if c.readRemaining > 0 && c.readErr == io.EOF { c.readErr = errUnexpectedEOF } @@ -1069,7 +1080,7 @@ func (r *messageReader) Read(b []byte) (int, error) { frameType, err := c.advanceFrame() switch { case err != nil: - c.readErr = hideTempErr(err) + c.readErr = err case frameType == TextMessage || frameType == BinaryMessage: c.readErr = errors.New("websocket: internal error, unexpected text or binary in Reader") } @@ -1094,7 +1105,7 @@ func (c *Conn) ReadMessage() (messageType int, p []byte, err error) { if err != nil { return messageType, nil, err } - p, err = ioutil.ReadAll(r) + p, err = io.ReadAll(r) return messageType, p, err } @@ -1136,7 +1147,8 @@ func (c *Conn) SetCloseHandler(h func(code int, text string) error) { if h == nil { h = func(code int, text string) error { message := FormatCloseMessage(code, "") - c.WriteControl(CloseMessage, message, time.Now().Add(writeWait)) + // Make a best effor to send the close message. + _ = c.WriteControl(CloseMessage, message, time.Now().Add(writeWait)) return nil } } @@ -1158,13 +1170,9 @@ func (c *Conn) PingHandler() func(appData string) error { func (c *Conn) SetPingHandler(h func(appData string) error) { if h == nil { h = func(message string) error { - err := c.WriteControl(PongMessage, []byte(message), time.Now().Add(writeWait)) - if err == ErrCloseSent { - return nil - } else if e, ok := err.(net.Error); ok && e.Temporary() { - return nil - } - return err + // Make a best effort to send the pong message. + _ = c.WriteControl(PongMessage, []byte(message), time.Now().Add(writeWait)) + return nil } } c.handlePing = h @@ -1189,8 +1197,16 @@ func (c *Conn) SetPongHandler(h func(appData string) error) { c.handlePong = h } +// NetConn returns the underlying connection that is wrapped by c. +// Note that writing to or reading from this connection directly will corrupt the +// WebSocket connection. +func (c *Conn) NetConn() net.Conn { + return c.conn +} + // UnderlyingConn returns the internal net.Conn. This can be used to further // modifications to connection specific flags. +// Deprecated: Use the NetConn method. func (c *Conn) UnderlyingConn() net.Conn { return c.conn } diff --git a/go-controller/vendor/github.com/gorilla/websocket/proxy.go b/go-controller/vendor/github.com/gorilla/websocket/proxy.go index e0f466b72f..d716a05884 100644 --- a/go-controller/vendor/github.com/gorilla/websocket/proxy.go +++ b/go-controller/vendor/github.com/gorilla/websocket/proxy.go @@ -6,34 +6,52 @@ package websocket import ( "bufio" + "bytes" + "context" "encoding/base64" "errors" "net" "net/http" "net/url" "strings" + + "golang.org/x/net/proxy" ) -type netDialerFunc func(network, addr string) (net.Conn, error) +type netDialerFunc func(ctx context.Context, network, addr string) (net.Conn, error) func (fn netDialerFunc) Dial(network, addr string) (net.Conn, error) { - return fn(network, addr) + return fn(context.Background(), network, addr) } -func init() { - proxy_RegisterDialerType("http", func(proxyURL *url.URL, forwardDialer proxy_Dialer) (proxy_Dialer, error) { - return &httpProxyDialer{proxyURL: proxyURL, forwardDial: forwardDialer.Dial}, nil - }) +func (fn netDialerFunc) DialContext(ctx context.Context, network, addr string) (net.Conn, error) { + return fn(ctx, network, addr) +} + +func proxyFromURL(proxyURL *url.URL, forwardDial netDialerFunc) (netDialerFunc, error) { + if proxyURL.Scheme == "http" || proxyURL.Scheme == "https" { + return (&httpProxyDialer{proxyURL: proxyURL, forwardDial: forwardDial}).DialContext, nil + } + dialer, err := proxy.FromURL(proxyURL, forwardDial) + if err != nil { + return nil, err + } + if d, ok := dialer.(proxy.ContextDialer); ok { + return d.DialContext, nil + } + return func(ctx context.Context, net, addr string) (net.Conn, error) { + return dialer.Dial(net, addr) + }, nil } type httpProxyDialer struct { proxyURL *url.URL - forwardDial func(network, addr string) (net.Conn, error) + forwardDial netDialerFunc } -func (hpd *httpProxyDialer) Dial(network string, addr string) (net.Conn, error) { +func (hpd *httpProxyDialer) DialContext(ctx context.Context, network string, addr string) (net.Conn, error) { hostPort, _ := hostPortNoPort(hpd.proxyURL) - conn, err := hpd.forwardDial(network, hostPort) + conn, err := hpd.forwardDial(ctx, network, hostPort) if err != nil { return nil, err } @@ -46,7 +64,6 @@ func (hpd *httpProxyDialer) Dial(network string, addr string) (net.Conn, error) connectHeader.Set("Proxy-Authorization", "Basic "+credential) } } - connectReq := &http.Request{ Method: http.MethodConnect, URL: &url.URL{Opaque: addr}, @@ -59,7 +76,7 @@ func (hpd *httpProxyDialer) Dial(network string, addr string) (net.Conn, error) return nil, err } - // Read response. It's OK to use and discard buffered reader here becaue + // Read response. It's OK to use and discard buffered reader here because // the remote server does not speak until spoken to. br := bufio.NewReader(conn) resp, err := http.ReadResponse(br, connectReq) @@ -68,8 +85,18 @@ func (hpd *httpProxyDialer) Dial(network string, addr string) (net.Conn, error) return nil, err } - if resp.StatusCode != 200 { - conn.Close() + // Close the response body to silence false positives from linters. Reset + // the buffered reader first to ensure that Close() does not read from + // conn. + // Note: Applications must call resp.Body.Close() on a response returned + // http.ReadResponse to inspect trailers or read another response from the + // buffered reader. The call to resp.Body.Close() does not release + // resources. + br.Reset(bytes.NewReader(nil)) + _ = resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + _ = conn.Close() f := strings.SplitN(resp.Status, " ", 2) return nil, errors.New(f[1]) } diff --git a/go-controller/vendor/github.com/gorilla/websocket/server.go b/go-controller/vendor/github.com/gorilla/websocket/server.go index 24d53b38ab..02ea01fdcd 100644 --- a/go-controller/vendor/github.com/gorilla/websocket/server.go +++ b/go-controller/vendor/github.com/gorilla/websocket/server.go @@ -6,8 +6,7 @@ package websocket import ( "bufio" - "errors" - "io" + "net" "net/http" "net/url" "strings" @@ -101,8 +100,8 @@ func checkSameOrigin(r *http.Request) bool { func (u *Upgrader) selectSubprotocol(r *http.Request, responseHeader http.Header) string { if u.Subprotocols != nil { clientProtocols := Subprotocols(r) - for _, serverProtocol := range u.Subprotocols { - for _, clientProtocol := range clientProtocols { + for _, clientProtocol := range clientProtocols { + for _, serverProtocol := range u.Subprotocols { if clientProtocol == serverProtocol { return clientProtocol } @@ -130,7 +129,8 @@ func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeade } if !tokenListContainsValue(r.Header, "Upgrade", "websocket") { - return u.returnError(w, r, http.StatusBadRequest, badHandshake+"'websocket' token not found in 'Upgrade' header") + w.Header().Set("Upgrade", "websocket") + return u.returnError(w, r, http.StatusUpgradeRequired, badHandshake+"'websocket' token not found in 'Upgrade' header") } if r.Method != http.MethodGet { @@ -154,8 +154,8 @@ func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeade } challengeKey := r.Header.Get("Sec-Websocket-Key") - if challengeKey == "" { - return u.returnError(w, r, http.StatusBadRequest, "websocket: not a websocket handshake: 'Sec-WebSocket-Key' header is missing or blank") + if !isValidChallengeKey(challengeKey) { + return u.returnError(w, r, http.StatusBadRequest, "websocket: not a websocket handshake: 'Sec-WebSocket-Key' header must be Base64 encoded value of 16-byte in length") } subprotocol := u.selectSubprotocol(r, responseHeader) @@ -172,28 +172,37 @@ func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeade } } - h, ok := w.(http.Hijacker) - if !ok { - return u.returnError(w, r, http.StatusInternalServerError, "websocket: response does not implement http.Hijacker") - } - var brw *bufio.ReadWriter - netConn, brw, err := h.Hijack() + netConn, brw, err := http.NewResponseController(w).Hijack() if err != nil { - return u.returnError(w, r, http.StatusInternalServerError, err.Error()) + return u.returnError(w, r, http.StatusInternalServerError, + "websocket: hijack: "+err.Error()) } - if brw.Reader.Buffered() > 0 { - netConn.Close() - return nil, errors.New("websocket: client sent data before handshake is complete") - } + // Close the network connection when returning an error. The variable + // netConn is set to nil before the success return at the end of the + // function. + defer func() { + if netConn != nil { + // It's safe to ignore the error from Close() because this code is + // only executed when returning a more important error to the + // application. + _ = netConn.Close() + } + }() var br *bufio.Reader - if u.ReadBufferSize == 0 && bufioReaderSize(netConn, brw.Reader) > 256 { - // Reuse hijacked buffered reader as connection reader. + if u.ReadBufferSize == 0 && brw.Reader.Size() > 256 { + // Use hijacked buffered reader as the connection reader. br = brw.Reader + } else if brw.Reader.Buffered() > 0 { + // Wrap the network connection to read buffered data in brw.Reader + // before reading from the network connection. This should be rare + // because a client must not send message data before receiving the + // handshake response. + netConn = &brNetConn{br: brw.Reader, Conn: netConn} } - buf := bufioWriterBuffer(netConn, brw.Writer) + buf := brw.Writer.AvailableBuffer() var writeBuf []byte if u.WriteBufferPool == nil && u.WriteBufferSize == 0 && len(buf) >= maxFrameHeaderSize+256 { @@ -247,20 +256,30 @@ func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeade } p = append(p, "\r\n"...) - // Clear deadlines set by HTTP server. - netConn.SetDeadline(time.Time{}) - if u.HandshakeTimeout > 0 { - netConn.SetWriteDeadline(time.Now().Add(u.HandshakeTimeout)) + if err := netConn.SetWriteDeadline(time.Now().Add(u.HandshakeTimeout)); err != nil { + return nil, err + } + } else { + // Clear deadlines set by HTTP server. + if err := netConn.SetDeadline(time.Time{}); err != nil { + return nil, err + } } + if _, err = netConn.Write(p); err != nil { - netConn.Close() return nil, err } if u.HandshakeTimeout > 0 { - netConn.SetWriteDeadline(time.Time{}) + if err := netConn.SetWriteDeadline(time.Time{}); err != nil { + return nil, err + } } + // Success! Set netConn to nil to stop the deferred function above from + // closing the network connection. + netConn = nil + return c, nil } @@ -327,39 +346,28 @@ func IsWebSocketUpgrade(r *http.Request) bool { tokenListContainsValue(r.Header, "Upgrade", "websocket") } -// bufioReaderSize size returns the size of a bufio.Reader. -func bufioReaderSize(originalReader io.Reader, br *bufio.Reader) int { - // This code assumes that peek on a reset reader returns - // bufio.Reader.buf[:0]. - // TODO: Use bufio.Reader.Size() after Go 1.10 - br.Reset(originalReader) - if p, err := br.Peek(0); err == nil { - return cap(p) - } - return 0 +type brNetConn struct { + br *bufio.Reader + net.Conn } -// writeHook is an io.Writer that records the last slice passed to it vio -// io.Writer.Write. -type writeHook struct { - p []byte +func (b *brNetConn) Read(p []byte) (n int, err error) { + if b.br != nil { + // Limit read to buferred data. + if n := b.br.Buffered(); len(p) > n { + p = p[:n] + } + n, err = b.br.Read(p) + if b.br.Buffered() == 0 { + b.br = nil + } + return n, err + } + return b.Conn.Read(p) } -func (wh *writeHook) Write(p []byte) (int, error) { - wh.p = p - return len(p), nil +// NetConn returns the underlying connection that is wrapped by b. +func (b *brNetConn) NetConn() net.Conn { + return b.Conn } -// bufioWriterBuffer grabs the buffer from a bufio.Writer. -func bufioWriterBuffer(originalWriter io.Writer, bw *bufio.Writer) []byte { - // This code assumes that bufio.Writer.buf[:1] is passed to the - // bufio.Writer's underlying writer. - var wh writeHook - bw.Reset(&wh) - bw.WriteByte(0) - bw.Flush() - - bw.Reset(originalWriter) - - return wh.p[:cap(wh.p)] -} diff --git a/go-controller/vendor/github.com/gorilla/websocket/tls_handshake.go b/go-controller/vendor/github.com/gorilla/websocket/tls_handshake.go deleted file mode 100644 index a62b68ccb1..0000000000 --- a/go-controller/vendor/github.com/gorilla/websocket/tls_handshake.go +++ /dev/null @@ -1,21 +0,0 @@ -//go:build go1.17 -// +build go1.17 - -package websocket - -import ( - "context" - "crypto/tls" -) - -func doHandshake(ctx context.Context, tlsConn *tls.Conn, cfg *tls.Config) error { - if err := tlsConn.HandshakeContext(ctx); err != nil { - return err - } - if !cfg.InsecureSkipVerify { - if err := tlsConn.VerifyHostname(cfg.ServerName); err != nil { - return err - } - } - return nil -} diff --git a/go-controller/vendor/github.com/gorilla/websocket/tls_handshake_116.go b/go-controller/vendor/github.com/gorilla/websocket/tls_handshake_116.go deleted file mode 100644 index e1b2b44f6e..0000000000 --- a/go-controller/vendor/github.com/gorilla/websocket/tls_handshake_116.go +++ /dev/null @@ -1,21 +0,0 @@ -//go:build !go1.17 -// +build !go1.17 - -package websocket - -import ( - "context" - "crypto/tls" -) - -func doHandshake(ctx context.Context, tlsConn *tls.Conn, cfg *tls.Config) error { - if err := tlsConn.Handshake(); err != nil { - return err - } - if !cfg.InsecureSkipVerify { - if err := tlsConn.VerifyHostname(cfg.ServerName); err != nil { - return err - } - } - return nil -} diff --git a/go-controller/vendor/github.com/gorilla/websocket/util.go b/go-controller/vendor/github.com/gorilla/websocket/util.go index 7bf2f66c67..31a5dee646 100644 --- a/go-controller/vendor/github.com/gorilla/websocket/util.go +++ b/go-controller/vendor/github.com/gorilla/websocket/util.go @@ -281,3 +281,18 @@ headers: } return result } + +// isValidChallengeKey checks if the argument meets RFC6455 specification. +func isValidChallengeKey(s string) bool { + // From RFC6455: + // + // A |Sec-WebSocket-Key| header field with a base64-encoded (see + // Section 4 of [RFC4648]) value that, when decoded, is 16 bytes in + // length. + + if s == "" { + return false + } + decoded, err := base64.StdEncoding.DecodeString(s) + return err == nil && len(decoded) == 16 +} diff --git a/go-controller/vendor/github.com/gorilla/websocket/x_net_proxy.go b/go-controller/vendor/github.com/gorilla/websocket/x_net_proxy.go deleted file mode 100644 index 2e668f6b88..0000000000 --- a/go-controller/vendor/github.com/gorilla/websocket/x_net_proxy.go +++ /dev/null @@ -1,473 +0,0 @@ -// Code generated by golang.org/x/tools/cmd/bundle. DO NOT EDIT. -//go:generate bundle -o x_net_proxy.go golang.org/x/net/proxy - -// Package proxy provides support for a variety of protocols to proxy network -// data. -// - -package websocket - -import ( - "errors" - "io" - "net" - "net/url" - "os" - "strconv" - "strings" - "sync" -) - -type proxy_direct struct{} - -// Direct is a direct proxy: one that makes network connections directly. -var proxy_Direct = proxy_direct{} - -func (proxy_direct) Dial(network, addr string) (net.Conn, error) { - return net.Dial(network, addr) -} - -// A PerHost directs connections to a default Dialer unless the host name -// requested matches one of a number of exceptions. -type proxy_PerHost struct { - def, bypass proxy_Dialer - - bypassNetworks []*net.IPNet - bypassIPs []net.IP - bypassZones []string - bypassHosts []string -} - -// NewPerHost returns a PerHost Dialer that directs connections to either -// defaultDialer or bypass, depending on whether the connection matches one of -// the configured rules. -func proxy_NewPerHost(defaultDialer, bypass proxy_Dialer) *proxy_PerHost { - return &proxy_PerHost{ - def: defaultDialer, - bypass: bypass, - } -} - -// Dial connects to the address addr on the given network through either -// defaultDialer or bypass. -func (p *proxy_PerHost) Dial(network, addr string) (c net.Conn, err error) { - host, _, err := net.SplitHostPort(addr) - if err != nil { - return nil, err - } - - return p.dialerForRequest(host).Dial(network, addr) -} - -func (p *proxy_PerHost) dialerForRequest(host string) proxy_Dialer { - if ip := net.ParseIP(host); ip != nil { - for _, net := range p.bypassNetworks { - if net.Contains(ip) { - return p.bypass - } - } - for _, bypassIP := range p.bypassIPs { - if bypassIP.Equal(ip) { - return p.bypass - } - } - return p.def - } - - for _, zone := range p.bypassZones { - if strings.HasSuffix(host, zone) { - return p.bypass - } - if host == zone[1:] { - // For a zone ".example.com", we match "example.com" - // too. - return p.bypass - } - } - for _, bypassHost := range p.bypassHosts { - if bypassHost == host { - return p.bypass - } - } - return p.def -} - -// AddFromString parses a string that contains comma-separated values -// specifying hosts that should use the bypass proxy. Each value is either an -// IP address, a CIDR range, a zone (*.example.com) or a host name -// (localhost). A best effort is made to parse the string and errors are -// ignored. -func (p *proxy_PerHost) AddFromString(s string) { - hosts := strings.Split(s, ",") - for _, host := range hosts { - host = strings.TrimSpace(host) - if len(host) == 0 { - continue - } - if strings.Contains(host, "/") { - // We assume that it's a CIDR address like 127.0.0.0/8 - if _, net, err := net.ParseCIDR(host); err == nil { - p.AddNetwork(net) - } - continue - } - if ip := net.ParseIP(host); ip != nil { - p.AddIP(ip) - continue - } - if strings.HasPrefix(host, "*.") { - p.AddZone(host[1:]) - continue - } - p.AddHost(host) - } -} - -// AddIP specifies an IP address that will use the bypass proxy. Note that -// this will only take effect if a literal IP address is dialed. A connection -// to a named host will never match an IP. -func (p *proxy_PerHost) AddIP(ip net.IP) { - p.bypassIPs = append(p.bypassIPs, ip) -} - -// AddNetwork specifies an IP range that will use the bypass proxy. Note that -// this will only take effect if a literal IP address is dialed. A connection -// to a named host will never match. -func (p *proxy_PerHost) AddNetwork(net *net.IPNet) { - p.bypassNetworks = append(p.bypassNetworks, net) -} - -// AddZone specifies a DNS suffix that will use the bypass proxy. A zone of -// "example.com" matches "example.com" and all of its subdomains. -func (p *proxy_PerHost) AddZone(zone string) { - if strings.HasSuffix(zone, ".") { - zone = zone[:len(zone)-1] - } - if !strings.HasPrefix(zone, ".") { - zone = "." + zone - } - p.bypassZones = append(p.bypassZones, zone) -} - -// AddHost specifies a host name that will use the bypass proxy. -func (p *proxy_PerHost) AddHost(host string) { - if strings.HasSuffix(host, ".") { - host = host[:len(host)-1] - } - p.bypassHosts = append(p.bypassHosts, host) -} - -// A Dialer is a means to establish a connection. -type proxy_Dialer interface { - // Dial connects to the given address via the proxy. - Dial(network, addr string) (c net.Conn, err error) -} - -// Auth contains authentication parameters that specific Dialers may require. -type proxy_Auth struct { - User, Password string -} - -// FromEnvironment returns the dialer specified by the proxy related variables in -// the environment. -func proxy_FromEnvironment() proxy_Dialer { - allProxy := proxy_allProxyEnv.Get() - if len(allProxy) == 0 { - return proxy_Direct - } - - proxyURL, err := url.Parse(allProxy) - if err != nil { - return proxy_Direct - } - proxy, err := proxy_FromURL(proxyURL, proxy_Direct) - if err != nil { - return proxy_Direct - } - - noProxy := proxy_noProxyEnv.Get() - if len(noProxy) == 0 { - return proxy - } - - perHost := proxy_NewPerHost(proxy, proxy_Direct) - perHost.AddFromString(noProxy) - return perHost -} - -// proxySchemes is a map from URL schemes to a function that creates a Dialer -// from a URL with such a scheme. -var proxy_proxySchemes map[string]func(*url.URL, proxy_Dialer) (proxy_Dialer, error) - -// RegisterDialerType takes a URL scheme and a function to generate Dialers from -// a URL with that scheme and a forwarding Dialer. Registered schemes are used -// by FromURL. -func proxy_RegisterDialerType(scheme string, f func(*url.URL, proxy_Dialer) (proxy_Dialer, error)) { - if proxy_proxySchemes == nil { - proxy_proxySchemes = make(map[string]func(*url.URL, proxy_Dialer) (proxy_Dialer, error)) - } - proxy_proxySchemes[scheme] = f -} - -// FromURL returns a Dialer given a URL specification and an underlying -// Dialer for it to make network requests. -func proxy_FromURL(u *url.URL, forward proxy_Dialer) (proxy_Dialer, error) { - var auth *proxy_Auth - if u.User != nil { - auth = new(proxy_Auth) - auth.User = u.User.Username() - if p, ok := u.User.Password(); ok { - auth.Password = p - } - } - - switch u.Scheme { - case "socks5": - return proxy_SOCKS5("tcp", u.Host, auth, forward) - } - - // If the scheme doesn't match any of the built-in schemes, see if it - // was registered by another package. - if proxy_proxySchemes != nil { - if f, ok := proxy_proxySchemes[u.Scheme]; ok { - return f(u, forward) - } - } - - return nil, errors.New("proxy: unknown scheme: " + u.Scheme) -} - -var ( - proxy_allProxyEnv = &proxy_envOnce{ - names: []string{"ALL_PROXY", "all_proxy"}, - } - proxy_noProxyEnv = &proxy_envOnce{ - names: []string{"NO_PROXY", "no_proxy"}, - } -) - -// envOnce looks up an environment variable (optionally by multiple -// names) once. It mitigates expensive lookups on some platforms -// (e.g. Windows). -// (Borrowed from net/http/transport.go) -type proxy_envOnce struct { - names []string - once sync.Once - val string -} - -func (e *proxy_envOnce) Get() string { - e.once.Do(e.init) - return e.val -} - -func (e *proxy_envOnce) init() { - for _, n := range e.names { - e.val = os.Getenv(n) - if e.val != "" { - return - } - } -} - -// SOCKS5 returns a Dialer that makes SOCKSv5 connections to the given address -// with an optional username and password. See RFC 1928 and RFC 1929. -func proxy_SOCKS5(network, addr string, auth *proxy_Auth, forward proxy_Dialer) (proxy_Dialer, error) { - s := &proxy_socks5{ - network: network, - addr: addr, - forward: forward, - } - if auth != nil { - s.user = auth.User - s.password = auth.Password - } - - return s, nil -} - -type proxy_socks5 struct { - user, password string - network, addr string - forward proxy_Dialer -} - -const proxy_socks5Version = 5 - -const ( - proxy_socks5AuthNone = 0 - proxy_socks5AuthPassword = 2 -) - -const proxy_socks5Connect = 1 - -const ( - proxy_socks5IP4 = 1 - proxy_socks5Domain = 3 - proxy_socks5IP6 = 4 -) - -var proxy_socks5Errors = []string{ - "", - "general failure", - "connection forbidden", - "network unreachable", - "host unreachable", - "connection refused", - "TTL expired", - "command not supported", - "address type not supported", -} - -// Dial connects to the address addr on the given network via the SOCKS5 proxy. -func (s *proxy_socks5) Dial(network, addr string) (net.Conn, error) { - switch network { - case "tcp", "tcp6", "tcp4": - default: - return nil, errors.New("proxy: no support for SOCKS5 proxy connections of type " + network) - } - - conn, err := s.forward.Dial(s.network, s.addr) - if err != nil { - return nil, err - } - if err := s.connect(conn, addr); err != nil { - conn.Close() - return nil, err - } - return conn, nil -} - -// connect takes an existing connection to a socks5 proxy server, -// and commands the server to extend that connection to target, -// which must be a canonical address with a host and port. -func (s *proxy_socks5) connect(conn net.Conn, target string) error { - host, portStr, err := net.SplitHostPort(target) - if err != nil { - return err - } - - port, err := strconv.Atoi(portStr) - if err != nil { - return errors.New("proxy: failed to parse port number: " + portStr) - } - if port < 1 || port > 0xffff { - return errors.New("proxy: port number out of range: " + portStr) - } - - // the size here is just an estimate - buf := make([]byte, 0, 6+len(host)) - - buf = append(buf, proxy_socks5Version) - if len(s.user) > 0 && len(s.user) < 256 && len(s.password) < 256 { - buf = append(buf, 2 /* num auth methods */, proxy_socks5AuthNone, proxy_socks5AuthPassword) - } else { - buf = append(buf, 1 /* num auth methods */, proxy_socks5AuthNone) - } - - if _, err := conn.Write(buf); err != nil { - return errors.New("proxy: failed to write greeting to SOCKS5 proxy at " + s.addr + ": " + err.Error()) - } - - if _, err := io.ReadFull(conn, buf[:2]); err != nil { - return errors.New("proxy: failed to read greeting from SOCKS5 proxy at " + s.addr + ": " + err.Error()) - } - if buf[0] != 5 { - return errors.New("proxy: SOCKS5 proxy at " + s.addr + " has unexpected version " + strconv.Itoa(int(buf[0]))) - } - if buf[1] == 0xff { - return errors.New("proxy: SOCKS5 proxy at " + s.addr + " requires authentication") - } - - // See RFC 1929 - if buf[1] == proxy_socks5AuthPassword { - buf = buf[:0] - buf = append(buf, 1 /* password protocol version */) - buf = append(buf, uint8(len(s.user))) - buf = append(buf, s.user...) - buf = append(buf, uint8(len(s.password))) - buf = append(buf, s.password...) - - if _, err := conn.Write(buf); err != nil { - return errors.New("proxy: failed to write authentication request to SOCKS5 proxy at " + s.addr + ": " + err.Error()) - } - - if _, err := io.ReadFull(conn, buf[:2]); err != nil { - return errors.New("proxy: failed to read authentication reply from SOCKS5 proxy at " + s.addr + ": " + err.Error()) - } - - if buf[1] != 0 { - return errors.New("proxy: SOCKS5 proxy at " + s.addr + " rejected username/password") - } - } - - buf = buf[:0] - buf = append(buf, proxy_socks5Version, proxy_socks5Connect, 0 /* reserved */) - - if ip := net.ParseIP(host); ip != nil { - if ip4 := ip.To4(); ip4 != nil { - buf = append(buf, proxy_socks5IP4) - ip = ip4 - } else { - buf = append(buf, proxy_socks5IP6) - } - buf = append(buf, ip...) - } else { - if len(host) > 255 { - return errors.New("proxy: destination host name too long: " + host) - } - buf = append(buf, proxy_socks5Domain) - buf = append(buf, byte(len(host))) - buf = append(buf, host...) - } - buf = append(buf, byte(port>>8), byte(port)) - - if _, err := conn.Write(buf); err != nil { - return errors.New("proxy: failed to write connect request to SOCKS5 proxy at " + s.addr + ": " + err.Error()) - } - - if _, err := io.ReadFull(conn, buf[:4]); err != nil { - return errors.New("proxy: failed to read connect reply from SOCKS5 proxy at " + s.addr + ": " + err.Error()) - } - - failure := "unknown error" - if int(buf[1]) < len(proxy_socks5Errors) { - failure = proxy_socks5Errors[buf[1]] - } - - if len(failure) > 0 { - return errors.New("proxy: SOCKS5 proxy at " + s.addr + " failed to connect: " + failure) - } - - bytesToDiscard := 0 - switch buf[3] { - case proxy_socks5IP4: - bytesToDiscard = net.IPv4len - case proxy_socks5IP6: - bytesToDiscard = net.IPv6len - case proxy_socks5Domain: - _, err := io.ReadFull(conn, buf[:1]) - if err != nil { - return errors.New("proxy: failed to read domain length from SOCKS5 proxy at " + s.addr + ": " + err.Error()) - } - bytesToDiscard = int(buf[0]) - default: - return errors.New("proxy: got unknown address type " + strconv.Itoa(int(buf[3])) + " from SOCKS5 proxy at " + s.addr) - } - - if cap(buf) < bytesToDiscard { - buf = make([]byte, bytesToDiscard) - } else { - buf = buf[:bytesToDiscard] - } - if _, err := io.ReadFull(conn, buf); err != nil { - return errors.New("proxy: failed to read address from SOCKS5 proxy at " + s.addr + ": " + err.Error()) - } - - // Also need to discard the port number - if _, err := io.ReadFull(conn, buf[:2]); err != nil { - return errors.New("proxy: failed to read port from SOCKS5 proxy at " + s.addr + ": " + err.Error()) - } - - return nil -} diff --git a/go-controller/vendor/github.com/prometheus/client_golang/NOTICE b/go-controller/vendor/github.com/prometheus/client_golang/NOTICE index dd878a30ee..b9cc55abbb 100644 --- a/go-controller/vendor/github.com/prometheus/client_golang/NOTICE +++ b/go-controller/vendor/github.com/prometheus/client_golang/NOTICE @@ -16,8 +16,3 @@ Go support for Protocol Buffers - Google's data interchange format http://github.com/golang/protobuf/ Copyright 2010 The Go Authors See source code for license details. - -Support for streaming Protocol Buffer messages for the Go language (golang). -https://github.com/matttproud/golang_protobuf_extensions -Copyright 2013 Matt T. Proud -Licensed under the Apache License, Version 2.0 diff --git a/go-controller/vendor/github.com/golang/protobuf/LICENSE b/go-controller/vendor/github.com/prometheus/client_golang/internal/github.com/golang/gddo/LICENSE similarity index 83% rename from go-controller/vendor/github.com/golang/protobuf/LICENSE rename to go-controller/vendor/github.com/prometheus/client_golang/internal/github.com/golang/gddo/LICENSE index 0f646931a4..65d761bc9f 100644 --- a/go-controller/vendor/github.com/golang/protobuf/LICENSE +++ b/go-controller/vendor/github.com/prometheus/client_golang/internal/github.com/golang/gddo/LICENSE @@ -1,16 +1,16 @@ -Copyright 2010 The Go Authors. All rights reserved. +Copyright (c) 2013 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of Google Inc. nor the names of its + * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. @@ -25,4 +25,3 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - diff --git a/go-controller/vendor/github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil/header/header.go b/go-controller/vendor/github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil/header/header.go new file mode 100644 index 0000000000..8547c8dfd1 --- /dev/null +++ b/go-controller/vendor/github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil/header/header.go @@ -0,0 +1,145 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd. + +// Package header provides functions for parsing HTTP headers. +package header + +import ( + "net/http" + "strings" +) + +// Octet types from RFC 2616. +var octetTypes [256]octetType + +type octetType byte + +const ( + isToken octetType = 1 << iota + isSpace +) + +func init() { + // OCTET = + // CHAR = + // CTL = + // CR = + // LF = + // SP = + // HT = + // <"> = + // CRLF = CR LF + // LWS = [CRLF] 1*( SP | HT ) + // TEXT = + // separators = "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\" | <"> + // | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT + // token = 1* + // qdtext = > + + for c := 0; c < 256; c++ { + var t octetType + isCtl := c <= 31 || c == 127 + isChar := 0 <= c && c <= 127 + isSeparator := strings.ContainsRune(" \t\"(),/:;<=>?@[]\\{}", rune(c)) + if strings.ContainsRune(" \t\r\n", rune(c)) { + t |= isSpace + } + if isChar && !isCtl && !isSeparator { + t |= isToken + } + octetTypes[c] = t + } +} + +// AcceptSpec describes an Accept* header. +type AcceptSpec struct { + Value string + Q float64 +} + +// ParseAccept parses Accept* headers. +func ParseAccept(header http.Header, key string) (specs []AcceptSpec) { +loop: + for _, s := range header[key] { + for { + var spec AcceptSpec + spec.Value, s = expectTokenSlash(s) + if spec.Value == "" { + continue loop + } + spec.Q = 1.0 + s = skipSpace(s) + if strings.HasPrefix(s, ";") { + s = skipSpace(s[1:]) + if !strings.HasPrefix(s, "q=") { + continue loop + } + spec.Q, s = expectQuality(s[2:]) + if spec.Q < 0.0 { + continue loop + } + } + specs = append(specs, spec) + s = skipSpace(s) + if !strings.HasPrefix(s, ",") { + continue loop + } + s = skipSpace(s[1:]) + } + } + return +} + +func skipSpace(s string) (rest string) { + i := 0 + for ; i < len(s); i++ { + if octetTypes[s[i]]&isSpace == 0 { + break + } + } + return s[i:] +} + +func expectTokenSlash(s string) (token, rest string) { + i := 0 + for ; i < len(s); i++ { + b := s[i] + if (octetTypes[b]&isToken == 0) && b != '/' { + break + } + } + return s[:i], s[i:] +} + +func expectQuality(s string) (q float64, rest string) { + switch { + case len(s) == 0: + return -1, "" + case s[0] == '0': + q = 0 + case s[0] == '1': + q = 1 + default: + return -1, "" + } + s = s[1:] + if !strings.HasPrefix(s, ".") { + return q, s + } + s = s[1:] + i := 0 + n := 0 + d := 1 + for ; i < len(s); i++ { + b := s[i] + if b < '0' || b > '9' { + break + } + n = n*10 + int(b) - '0' + d *= 10 + } + return q + float64(n)/float64(d), s[i:] +} diff --git a/go-controller/vendor/github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil/negotiate.go b/go-controller/vendor/github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil/negotiate.go new file mode 100644 index 0000000000..2e45780b74 --- /dev/null +++ b/go-controller/vendor/github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil/negotiate.go @@ -0,0 +1,36 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd. + +package httputil + +import ( + "net/http" + + "github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil/header" +) + +// NegotiateContentEncoding returns the best offered content encoding for the +// request's Accept-Encoding header. If two offers match with equal weight and +// then the offer earlier in the list is preferred. If no offers are +// acceptable, then "" is returned. +func NegotiateContentEncoding(r *http.Request, offers []string) string { + bestOffer := "identity" + bestQ := -1.0 + specs := header.ParseAccept(r.Header, "Accept-Encoding") + for _, offer := range offers { + for _, spec := range specs { + if spec.Q > bestQ && + (spec.Value == "*" || spec.Value == offer) { + bestQ = spec.Q + bestOffer = offer + } + } + } + if bestQ == 0 { + bestOffer = "" + } + return bestOffer +} diff --git a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/collectorfunc.go b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/collectorfunc.go new file mode 100644 index 0000000000..9a71a15db1 --- /dev/null +++ b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/collectorfunc.go @@ -0,0 +1,30 @@ +// Copyright 2025 The Prometheus Authors +// 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 prometheus + +// CollectorFunc is a convenient way to implement a Prometheus Collector +// without interface boilerplate. +// This implementation is based on DescribeByCollect method. +// familiarize yourself to it before using. +type CollectorFunc func(chan<- Metric) + +// Collect calls the defined CollectorFunc function with the provided Metrics channel +func (f CollectorFunc) Collect(ch chan<- Metric) { + f(ch) +} + +// Describe sends the descriptor information using DescribeByCollect +func (f CollectorFunc) Describe(ch chan<- *Desc) { + DescribeByCollect(f, ch) +} diff --git a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/collectors/go_collector_latest.go b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/collectors/go_collector_latest.go index bcfa4fa10e..cc4ef1077e 100644 --- a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/collectors/go_collector_latest.go +++ b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/collectors/go_collector_latest.go @@ -37,6 +37,9 @@ var ( // MetricsScheduler allows only scheduler metrics to be collected from Go runtime. // e.g. go_sched_goroutines_goroutines MetricsScheduler = GoRuntimeMetricsRule{regexp.MustCompile(`^/sched/.*`)} + // MetricsDebug allows only debug metrics to be collected from Go runtime. + // e.g. go_godebug_non_default_behavior_gocachetest_events_total + MetricsDebug = GoRuntimeMetricsRule{regexp.MustCompile(`^/godebug/.*`)} ) // WithGoCollectorMemStatsMetricsDisabled disables metrics that is gathered in runtime.MemStats structure such as: @@ -44,7 +47,6 @@ var ( // go_memstats_alloc_bytes // go_memstats_alloc_bytes_total // go_memstats_sys_bytes -// go_memstats_lookups_total // go_memstats_mallocs_total // go_memstats_frees_total // go_memstats_heap_alloc_bytes diff --git a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/desc.go b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/desc.go index 68ffe3c248..ad347113c0 100644 --- a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/desc.go +++ b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/desc.go @@ -189,12 +189,15 @@ func (d *Desc) String() string { fmt.Sprintf("%s=%q", lp.GetName(), lp.GetValue()), ) } - vlStrings := make([]string, 0, len(d.variableLabels.names)) - for _, vl := range d.variableLabels.names { - if fn, ok := d.variableLabels.labelConstraints[vl]; ok && fn != nil { - vlStrings = append(vlStrings, fmt.Sprintf("c(%s)", vl)) - } else { - vlStrings = append(vlStrings, vl) + vlStrings := []string{} + if d.variableLabels != nil { + vlStrings = make([]string, 0, len(d.variableLabels.names)) + for _, vl := range d.variableLabels.names { + if fn, ok := d.variableLabels.labelConstraints[vl]; ok && fn != nil { + vlStrings = append(vlStrings, fmt.Sprintf("c(%s)", vl)) + } else { + vlStrings = append(vlStrings, vl) + } } } return fmt.Sprintf( diff --git a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/go_collector.go b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/go_collector.go index ad9a71a5e0..520cbd7d41 100644 --- a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/go_collector.go +++ b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/go_collector.go @@ -22,13 +22,13 @@ import ( // goRuntimeMemStats provides the metrics initially provided by runtime.ReadMemStats. // From Go 1.17 those similar (and better) statistics are provided by runtime/metrics, so // while eval closure works on runtime.MemStats, the struct from Go 1.17+ is -// populated using runtime/metrics. +// populated using runtime/metrics. Those are the defaults we can't alter. func goRuntimeMemStats() memStatsMetrics { return memStatsMetrics{ { desc: NewDesc( memstatNamespace("alloc_bytes"), - "Number of bytes allocated and still in use.", + "Number of bytes allocated in heap and currently in use. Equals to /memory/classes/heap/objects:bytes.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.Alloc) }, @@ -36,7 +36,7 @@ func goRuntimeMemStats() memStatsMetrics { }, { desc: NewDesc( memstatNamespace("alloc_bytes_total"), - "Total number of bytes allocated, even if freed.", + "Total number of bytes allocated in heap until now, even if released already. Equals to /gc/heap/allocs:bytes.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.TotalAlloc) }, @@ -44,23 +44,16 @@ func goRuntimeMemStats() memStatsMetrics { }, { desc: NewDesc( memstatNamespace("sys_bytes"), - "Number of bytes obtained from system.", + "Number of bytes obtained from system. Equals to /memory/classes/total:byte.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.Sys) }, valType: GaugeValue, - }, { - desc: NewDesc( - memstatNamespace("lookups_total"), - "Total number of pointer lookups.", - nil, nil, - ), - eval: func(ms *runtime.MemStats) float64 { return float64(ms.Lookups) }, - valType: CounterValue, }, { desc: NewDesc( memstatNamespace("mallocs_total"), - "Total number of mallocs.", + // TODO(bwplotka): We could add go_memstats_heap_objects, probably useful for discovery. Let's gather more feedback, kind of a waste of bytes for everybody for compatibility reasons to keep both, and we can't really rename/remove useful metric. + "Total number of heap objects allocated, both live and gc-ed. Semantically a counter version for go_memstats_heap_objects gauge. Equals to /gc/heap/allocs:objects + /gc/heap/tiny/allocs:objects.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.Mallocs) }, @@ -68,7 +61,7 @@ func goRuntimeMemStats() memStatsMetrics { }, { desc: NewDesc( memstatNamespace("frees_total"), - "Total number of frees.", + "Total number of heap objects frees. Equals to /gc/heap/frees:objects + /gc/heap/tiny/allocs:objects.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.Frees) }, @@ -76,7 +69,7 @@ func goRuntimeMemStats() memStatsMetrics { }, { desc: NewDesc( memstatNamespace("heap_alloc_bytes"), - "Number of heap bytes allocated and still in use.", + "Number of heap bytes allocated and currently in use, same as go_memstats_alloc_bytes. Equals to /memory/classes/heap/objects:bytes.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapAlloc) }, @@ -84,7 +77,7 @@ func goRuntimeMemStats() memStatsMetrics { }, { desc: NewDesc( memstatNamespace("heap_sys_bytes"), - "Number of heap bytes obtained from system.", + "Number of heap bytes obtained from system. Equals to /memory/classes/heap/objects:bytes + /memory/classes/heap/unused:bytes + /memory/classes/heap/released:bytes + /memory/classes/heap/free:bytes.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapSys) }, @@ -92,7 +85,7 @@ func goRuntimeMemStats() memStatsMetrics { }, { desc: NewDesc( memstatNamespace("heap_idle_bytes"), - "Number of heap bytes waiting to be used.", + "Number of heap bytes waiting to be used. Equals to /memory/classes/heap/released:bytes + /memory/classes/heap/free:bytes.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapIdle) }, @@ -100,7 +93,7 @@ func goRuntimeMemStats() memStatsMetrics { }, { desc: NewDesc( memstatNamespace("heap_inuse_bytes"), - "Number of heap bytes that are in use.", + "Number of heap bytes that are in use. Equals to /memory/classes/heap/objects:bytes + /memory/classes/heap/unused:bytes", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapInuse) }, @@ -108,7 +101,7 @@ func goRuntimeMemStats() memStatsMetrics { }, { desc: NewDesc( memstatNamespace("heap_released_bytes"), - "Number of heap bytes released to OS.", + "Number of heap bytes released to OS. Equals to /memory/classes/heap/released:bytes.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapReleased) }, @@ -116,7 +109,7 @@ func goRuntimeMemStats() memStatsMetrics { }, { desc: NewDesc( memstatNamespace("heap_objects"), - "Number of allocated objects.", + "Number of currently allocated objects. Equals to /gc/heap/objects:objects.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapObjects) }, @@ -124,7 +117,7 @@ func goRuntimeMemStats() memStatsMetrics { }, { desc: NewDesc( memstatNamespace("stack_inuse_bytes"), - "Number of bytes in use by the stack allocator.", + "Number of bytes obtained from system for stack allocator in non-CGO environments. Equals to /memory/classes/heap/stacks:bytes.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.StackInuse) }, @@ -132,7 +125,7 @@ func goRuntimeMemStats() memStatsMetrics { }, { desc: NewDesc( memstatNamespace("stack_sys_bytes"), - "Number of bytes obtained from system for stack allocator.", + "Number of bytes obtained from system for stack allocator. Equals to /memory/classes/heap/stacks:bytes + /memory/classes/os-stacks:bytes.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.StackSys) }, @@ -140,7 +133,7 @@ func goRuntimeMemStats() memStatsMetrics { }, { desc: NewDesc( memstatNamespace("mspan_inuse_bytes"), - "Number of bytes in use by mspan structures.", + "Number of bytes in use by mspan structures. Equals to /memory/classes/metadata/mspan/inuse:bytes.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.MSpanInuse) }, @@ -148,7 +141,7 @@ func goRuntimeMemStats() memStatsMetrics { }, { desc: NewDesc( memstatNamespace("mspan_sys_bytes"), - "Number of bytes used for mspan structures obtained from system.", + "Number of bytes used for mspan structures obtained from system. Equals to /memory/classes/metadata/mspan/inuse:bytes + /memory/classes/metadata/mspan/free:bytes.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.MSpanSys) }, @@ -156,7 +149,7 @@ func goRuntimeMemStats() memStatsMetrics { }, { desc: NewDesc( memstatNamespace("mcache_inuse_bytes"), - "Number of bytes in use by mcache structures.", + "Number of bytes in use by mcache structures. Equals to /memory/classes/metadata/mcache/inuse:bytes.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.MCacheInuse) }, @@ -164,7 +157,7 @@ func goRuntimeMemStats() memStatsMetrics { }, { desc: NewDesc( memstatNamespace("mcache_sys_bytes"), - "Number of bytes used for mcache structures obtained from system.", + "Number of bytes used for mcache structures obtained from system. Equals to /memory/classes/metadata/mcache/inuse:bytes + /memory/classes/metadata/mcache/free:bytes.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.MCacheSys) }, @@ -172,7 +165,7 @@ func goRuntimeMemStats() memStatsMetrics { }, { desc: NewDesc( memstatNamespace("buck_hash_sys_bytes"), - "Number of bytes used by the profiling bucket hash table.", + "Number of bytes used by the profiling bucket hash table. Equals to /memory/classes/profiling/buckets:bytes.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.BuckHashSys) }, @@ -180,7 +173,7 @@ func goRuntimeMemStats() memStatsMetrics { }, { desc: NewDesc( memstatNamespace("gc_sys_bytes"), - "Number of bytes used for garbage collection system metadata.", + "Number of bytes used for garbage collection system metadata. Equals to /memory/classes/metadata/other:bytes.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.GCSys) }, @@ -188,7 +181,7 @@ func goRuntimeMemStats() memStatsMetrics { }, { desc: NewDesc( memstatNamespace("other_sys_bytes"), - "Number of bytes used for other system allocations.", + "Number of bytes used for other system allocations. Equals to /memory/classes/other:bytes.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.OtherSys) }, @@ -196,7 +189,7 @@ func goRuntimeMemStats() memStatsMetrics { }, { desc: NewDesc( memstatNamespace("next_gc_bytes"), - "Number of heap bytes when next garbage collection will take place.", + "Number of heap bytes when next garbage collection will take place. Equals to /gc/heap/goal:bytes.", nil, nil, ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.NextGC) }, @@ -225,7 +218,7 @@ func newBaseGoCollector() baseGoCollector { nil, nil), gcDesc: NewDesc( "go_gc_duration_seconds", - "A summary of the pause duration of garbage collection cycles.", + "A summary of the wall-time pause (stop-the-world) duration in garbage collection cycles.", nil, nil), gcLastTimeDesc: NewDesc( "go_memstats_last_gc_time_seconds", diff --git a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/go_collector_latest.go b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/go_collector_latest.go index 2d8d9f64f4..6b8684731c 100644 --- a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/go_collector_latest.go +++ b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/go_collector_latest.go @@ -17,6 +17,7 @@ package prometheus import ( + "fmt" "math" "runtime" "runtime/metrics" @@ -153,7 +154,8 @@ func defaultGoCollectorOptions() internal.GoCollectorOptions { "/gc/heap/frees-by-size:bytes": goGCHeapFreesBytes, }, RuntimeMetricRules: []internal.GoCollectorRule{ - //{Matcher: regexp.MustCompile("")}, + // Recommended metrics we want by default from runtime/metrics. + {Matcher: internal.GoCollectorDefaultRuntimeMetrics}, }, } } @@ -203,6 +205,7 @@ func NewGoCollector(opts ...func(o *internal.GoCollectorOptions)) Collector { // to fail here. This condition is tested in TestExpectedRuntimeMetrics. continue } + help := attachOriginalName(d.Description.Description, d.Name) sampleBuf = append(sampleBuf, metrics.Sample{Name: d.Name}) sampleMap[d.Name] = &sampleBuf[len(sampleBuf)-1] @@ -214,7 +217,7 @@ func NewGoCollector(opts ...func(o *internal.GoCollectorOptions)) Collector { m = newBatchHistogram( NewDesc( BuildFQName(namespace, subsystem, name), - d.Description.Description, + help, nil, nil, ), @@ -226,7 +229,7 @@ func NewGoCollector(opts ...func(o *internal.GoCollectorOptions)) Collector { Namespace: namespace, Subsystem: subsystem, Name: name, - Help: d.Description.Description, + Help: help, }, ) } else { @@ -234,7 +237,7 @@ func NewGoCollector(opts ...func(o *internal.GoCollectorOptions)) Collector { Namespace: namespace, Subsystem: subsystem, Name: name, - Help: d.Description.Description, + Help: help, }) } metricSet = append(metricSet, m) @@ -284,6 +287,10 @@ func NewGoCollector(opts ...func(o *internal.GoCollectorOptions)) Collector { } } +func attachOriginalName(desc, origName string) string { + return fmt.Sprintf("%s Sourced from %s.", desc, origName) +} + // Describe returns all descriptions of the collector. func (c *goCollector) Describe(ch chan<- *Desc) { c.base.Describe(ch) @@ -376,13 +383,13 @@ func unwrapScalarRMValue(v metrics.Value) float64 { // // This should never happen because we always populate our metric // set from the runtime/metrics package. - panic("unexpected unsupported metric") + panic("unexpected bad kind metric") default: // Unsupported metric kind. // // This should never happen because we check for this during initialization // and flag and filter metrics whose kinds we don't understand. - panic("unexpected unsupported metric kind") + panic(fmt.Sprintf("unexpected unsupported metric: %v", v.Kind())) } } diff --git a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/histogram.go b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/histogram.go index b5c8bcb395..c453b754a7 100644 --- a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/histogram.go +++ b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/histogram.go @@ -14,6 +14,7 @@ package prometheus import ( + "errors" "fmt" "math" "runtime" @@ -28,6 +29,11 @@ import ( "google.golang.org/protobuf/types/known/timestamppb" ) +const ( + nativeHistogramSchemaMaximum = 8 + nativeHistogramSchemaMinimum = -4 +) + // nativeHistogramBounds for the frac of observed values. Only relevant for // schema > 0. The position in the slice is the schema. (0 is never used, just // here for convenience of using the schema directly as the index.) @@ -330,11 +336,11 @@ func ExponentialBuckets(start, factor float64, count int) []float64 { // used for the Buckets field of HistogramOpts. // // The function panics if 'count' is 0 or negative, if 'min' is 0 or negative. -func ExponentialBucketsRange(min, max float64, count int) []float64 { +func ExponentialBucketsRange(minBucket, maxBucket float64, count int) []float64 { if count < 1 { panic("ExponentialBucketsRange count needs a positive count") } - if min <= 0 { + if minBucket <= 0 { panic("ExponentialBucketsRange min needs to be greater than 0") } @@ -342,12 +348,12 @@ func ExponentialBucketsRange(min, max float64, count int) []float64 { // max = min*growthFactor^(bucketCount-1) // We know max/min and highest bucket. Solve for growthFactor. - growthFactor := math.Pow(max/min, 1.0/float64(count-1)) + growthFactor := math.Pow(maxBucket/minBucket, 1.0/float64(count-1)) // Now that we know growthFactor, solve for each bucket. buckets := make([]float64, count) for i := 1; i <= count; i++ { - buckets[i-1] = min * math.Pow(growthFactor, float64(i-1)) + buckets[i-1] = minBucket * math.Pow(growthFactor, float64(i-1)) } return buckets } @@ -440,7 +446,7 @@ type HistogramOpts struct { // constant (or any negative float value). NativeHistogramZeroThreshold float64 - // The remaining fields define a strategy to limit the number of + // The next three fields define a strategy to limit the number of // populated sparse buckets. If NativeHistogramMaxBucketNumber is left // at zero, the number of buckets is not limited. (Note that this might // lead to unbounded memory consumption if the values observed by the @@ -473,6 +479,22 @@ type HistogramOpts struct { NativeHistogramMinResetDuration time.Duration NativeHistogramMaxZeroThreshold float64 + // NativeHistogramMaxExemplars limits the number of exemplars + // that are kept in memory for each native histogram. If you leave it at + // zero, a default value of 10 is used. If no exemplars should be kept specifically + // for native histograms, set it to a negative value. (Scrapers can + // still use the exemplars exposed for classic buckets, which are managed + // independently.) + NativeHistogramMaxExemplars int + // NativeHistogramExemplarTTL is only checked once + // NativeHistogramMaxExemplars is exceeded. In that case, the + // oldest exemplar is removed if it is older than NativeHistogramExemplarTTL. + // Otherwise, the older exemplar in the pair of exemplars that are closest + // together (on an exponential scale) is removed. + // If NativeHistogramExemplarTTL is left at its zero value, a default value of + // 5m is used. To always delete the oldest exemplar, set it to a negative value. + NativeHistogramExemplarTTL time.Duration + // now is for testing purposes, by default it's time.Now. now func() time.Time @@ -532,6 +554,7 @@ func newHistogram(desc *Desc, opts HistogramOpts, labelValues ...string) Histogr if opts.afterFunc == nil { opts.afterFunc = time.AfterFunc } + h := &histogram{ desc: desc, upperBounds: opts.Buckets, @@ -556,6 +579,7 @@ func newHistogram(desc *Desc, opts HistogramOpts, labelValues ...string) Histogr h.nativeHistogramZeroThreshold = DefNativeHistogramZeroThreshold } // Leave h.nativeHistogramZeroThreshold at 0 otherwise. h.nativeHistogramSchema = pickSchema(opts.NativeHistogramBucketFactor) + h.nativeExemplars = makeNativeExemplars(opts.NativeHistogramExemplarTTL, opts.NativeHistogramMaxExemplars) } for i, upperBound := range h.upperBounds { if i < len(h.upperBounds)-1 { @@ -725,7 +749,8 @@ type histogram struct { // resetScheduled is protected by mtx. It is true if a reset is // scheduled for a later time (when nativeHistogramMinResetDuration has // passed). - resetScheduled bool + resetScheduled bool + nativeExemplars nativeExemplars // now is for testing purposes, by default it's time.Now. now func() time.Time @@ -742,6 +767,9 @@ func (h *histogram) Observe(v float64) { h.observe(v, h.findBucket(v)) } +// ObserveWithExemplar should not be called in a high-frequency setting +// for a native histogram with configured exemplars. For this case, +// the implementation isn't lock-free and might suffer from lock contention. func (h *histogram) ObserveWithExemplar(v float64, e Labels) { i := h.findBucket(v) h.observe(v, i) @@ -821,6 +849,13 @@ func (h *histogram) Write(out *dto.Metric) error { Length: proto.Uint32(0), }} } + + if h.nativeExemplars.isEnabled() { + h.nativeExemplars.Lock() + his.Exemplars = append(his.Exemplars, h.nativeExemplars.exemplars...) + h.nativeExemplars.Unlock() + } + } addAndResetCounts(hotCounts, coldCounts) return nil @@ -829,15 +864,35 @@ func (h *histogram) Write(out *dto.Metric) error { // findBucket returns the index of the bucket for the provided value, or // len(h.upperBounds) for the +Inf bucket. func (h *histogram) findBucket(v float64) int { - // TODO(beorn7): For small numbers of buckets (<30), a linear search is - // slightly faster than the binary search. If we really care, we could - // switch from one search strategy to the other depending on the number - // of buckets. - // - // Microbenchmarks (BenchmarkHistogramNoLabels): - // 11 buckets: 38.3 ns/op linear - binary 48.7 ns/op - // 100 buckets: 78.1 ns/op linear - binary 54.9 ns/op - // 300 buckets: 154 ns/op linear - binary 61.6 ns/op + n := len(h.upperBounds) + if n == 0 { + return 0 + } + + // Early exit: if v is less than or equal to the first upper bound, return 0 + if v <= h.upperBounds[0] { + return 0 + } + + // Early exit: if v is greater than the last upper bound, return len(h.upperBounds) + if v > h.upperBounds[n-1] { + return n + } + + // For small arrays, use simple linear search + // "magic number" 35 is result of tests on couple different (AWS and baremetal) servers + // see more details here: https://github.com/prometheus/client_golang/pull/1662 + if n < 35 { + for i, bound := range h.upperBounds { + if v <= bound { + return i + } + } + // If v is greater than all upper bounds, return len(h.upperBounds) + return n + } + + // For larger arrays, use stdlib's binary search return sort.SearchFloat64s(h.upperBounds, v) } @@ -1091,8 +1146,10 @@ func (h *histogram) resetCounts(counts *histogramCounts) { deleteSyncMap(&counts.nativeHistogramBucketsPositive) } -// updateExemplar replaces the exemplar for the provided bucket. With empty -// labels, it's a no-op. It panics if any of the labels is invalid. +// updateExemplar replaces the exemplar for the provided classic bucket. +// With empty labels, it's a no-op. It panics if any of the labels is invalid. +// If histogram is native, the exemplar will be cached into nativeExemplars, +// which has a limit, and will remove one exemplar when limit is reached. func (h *histogram) updateExemplar(v float64, bucket int, l Labels) { if l == nil { return @@ -1102,6 +1159,10 @@ func (h *histogram) updateExemplar(v float64, bucket int, l Labels) { panic(err) } h.exemplars[bucket].Store(e) + doSparse := h.nativeHistogramSchema > math.MinInt32 && !math.IsNaN(v) + if doSparse { + h.nativeExemplars.addExemplar(e) + } } // HistogramVec is a Collector that bundles a set of Histograms that all share the @@ -1336,6 +1397,48 @@ func MustNewConstHistogram( return m } +// NewConstHistogramWithCreatedTimestamp does the same thing as NewConstHistogram but sets the created timestamp. +func NewConstHistogramWithCreatedTimestamp( + desc *Desc, + count uint64, + sum float64, + buckets map[float64]uint64, + ct time.Time, + labelValues ...string, +) (Metric, error) { + if desc.err != nil { + return nil, desc.err + } + if err := validateLabelValues(labelValues, len(desc.variableLabels.names)); err != nil { + return nil, err + } + return &constHistogram{ + desc: desc, + count: count, + sum: sum, + buckets: buckets, + labelPairs: MakeLabelPairs(desc, labelValues), + createdTs: timestamppb.New(ct), + }, nil +} + +// MustNewConstHistogramWithCreatedTimestamp is a version of NewConstHistogramWithCreatedTimestamp that panics where +// NewConstHistogramWithCreatedTimestamp would have returned an error. +func MustNewConstHistogramWithCreatedTimestamp( + desc *Desc, + count uint64, + sum float64, + buckets map[float64]uint64, + ct time.Time, + labelValues ...string, +) Metric { + m, err := NewConstHistogramWithCreatedTimestamp(desc, count, sum, buckets, ct, labelValues...) + if err != nil { + panic(err) + } + return m +} + type buckSort []*dto.Bucket func (s buckSort) Len() int { @@ -1363,9 +1466,9 @@ func pickSchema(bucketFactor float64) int32 { floor := math.Floor(math.Log2(math.Log2(bucketFactor))) switch { case floor <= -8: - return 8 + return nativeHistogramSchemaMaximum case floor >= 4: - return -4 + return nativeHistogramSchemaMinimum default: return -int32(floor) } @@ -1575,3 +1678,379 @@ func addAndResetCounts(hot, cold *histogramCounts) { atomic.AddUint64(&hot.nativeHistogramZeroBucket, atomic.LoadUint64(&cold.nativeHistogramZeroBucket)) atomic.StoreUint64(&cold.nativeHistogramZeroBucket, 0) } + +type nativeExemplars struct { + sync.Mutex + + // Time-to-live for exemplars, it is set to -1 if exemplars are disabled, that is NativeHistogramMaxExemplars is below 0. + // The ttl is used on insertion to remove an exemplar that is older than ttl, if present. + ttl time.Duration + + exemplars []*dto.Exemplar +} + +func (n *nativeExemplars) isEnabled() bool { + return n.ttl != -1 +} + +func makeNativeExemplars(ttl time.Duration, maxCount int) nativeExemplars { + if ttl == 0 { + ttl = 5 * time.Minute + } + + if maxCount == 0 { + maxCount = 10 + } + + if maxCount < 0 { + maxCount = 0 + ttl = -1 + } + + return nativeExemplars{ + ttl: ttl, + exemplars: make([]*dto.Exemplar, 0, maxCount), + } +} + +func (n *nativeExemplars) addExemplar(e *dto.Exemplar) { + if !n.isEnabled() { + return + } + + n.Lock() + defer n.Unlock() + + // When the number of exemplars has not yet exceeded or + // is equal to cap(n.exemplars), then + // insert the new exemplar directly. + if len(n.exemplars) < cap(n.exemplars) { + var nIdx int + for nIdx = 0; nIdx < len(n.exemplars); nIdx++ { + if *e.Value < *n.exemplars[nIdx].Value { + break + } + } + n.exemplars = append(n.exemplars[:nIdx], append([]*dto.Exemplar{e}, n.exemplars[nIdx:]...)...) + return + } + + if len(n.exemplars) == 1 { + // When the number of exemplars is 1, then + // replace the existing exemplar with the new exemplar. + n.exemplars[0] = e + return + } + // From this point on, the number of exemplars is greater than 1. + + // When the number of exemplars exceeds the limit, remove one exemplar. + var ( + ot = time.Time{} // Oldest timestamp seen. Initial value doesn't matter as we replace it due to otIdx == -1 in the loop. + otIdx = -1 // Index of the exemplar with the oldest timestamp. + + md = -1.0 // Logarithm of the delta of the closest pair of exemplars. + + // The insertion point of the new exemplar in the exemplars slice after insertion. + // This is calculated purely based on the order of the exemplars by value. + // nIdx == len(n.exemplars) means the new exemplar is to be inserted after the end. + nIdx = -1 + + // rIdx is ultimately the index for the exemplar that we are replacing with the new exemplar. + // The aim is to keep a good spread of exemplars by value and not let them bunch up too much. + // It is calculated in 3 steps: + // 1. First we set rIdx to the index of the older exemplar within the closest pair by value. + // That is the following will be true (on log scale): + // either the exemplar pair on index (rIdx-1, rIdx) or (rIdx, rIdx+1) will have + // the closest values to each other from all pairs. + // For example, suppose the values are distributed like this: + // |-----------x-------------x----------------x----x-----| + // ^--rIdx as this is older. + // Or like this: + // |-----------x-------------x----------------x----x-----| + // ^--rIdx as this is older. + // 2. If there is an exemplar that expired, then we simple reset rIdx to that index. + // 3. We check if by inserting the new exemplar we would create a closer pair at + // (nIdx-1, nIdx) or (nIdx, nIdx+1) and set rIdx to nIdx-1 or nIdx accordingly to + // keep the spread of exemplars by value; otherwise we keep rIdx as it is. + rIdx = -1 + cLog float64 // Logarithm of the current exemplar. + pLog float64 // Logarithm of the previous exemplar. + ) + + for i, exemplar := range n.exemplars { + // Find the exemplar with the oldest timestamp. + if otIdx == -1 || exemplar.Timestamp.AsTime().Before(ot) { + ot = exemplar.Timestamp.AsTime() + otIdx = i + } + + // Find the index at which to insert new the exemplar. + if nIdx == -1 && *e.Value <= *exemplar.Value { + nIdx = i + } + + // Find the two closest exemplars and pick the one the with older timestamp. + pLog = cLog + cLog = math.Log(exemplar.GetValue()) + if i == 0 { + continue + } + diff := math.Abs(cLog - pLog) + if md == -1 || diff < md { + // The closest exemplar pair is at index: i-1, i. + // Choose the exemplar with the older timestamp for replacement. + md = diff + if n.exemplars[i].Timestamp.AsTime().Before(n.exemplars[i-1].Timestamp.AsTime()) { + rIdx = i + } else { + rIdx = i - 1 + } + } + + } + + // If all existing exemplar are smaller than new exemplar, + // then the exemplar should be inserted at the end. + if nIdx == -1 { + nIdx = len(n.exemplars) + } + // Here, we have the following relationships: + // n.exemplars[nIdx-1].Value < e.Value (if nIdx > 0) + // e.Value <= n.exemplars[nIdx].Value (if nIdx < len(n.exemplars)) + + if otIdx != -1 && e.Timestamp.AsTime().Sub(ot) > n.ttl { + // If the oldest exemplar has expired, then replace it with the new exemplar. + rIdx = otIdx + } else { + // In the previous for loop, when calculating the closest pair of exemplars, + // we did not take into account the newly inserted exemplar. + // So we need to calculate with the newly inserted exemplar again. + elog := math.Log(e.GetValue()) + if nIdx > 0 { + diff := math.Abs(elog - math.Log(n.exemplars[nIdx-1].GetValue())) + if diff < md { + // The value we are about to insert is closer to the previous exemplar at the insertion point than what we calculated before in rIdx. + // v--rIdx + // |-----------x-n-----------x----------------x----x-----| + // nIdx-1--^ ^--new exemplar value + // Do not make the spread worse, replace nIdx-1 and not rIdx. + md = diff + rIdx = nIdx - 1 + } + } + if nIdx < len(n.exemplars) { + diff := math.Abs(math.Log(n.exemplars[nIdx].GetValue()) - elog) + if diff < md { + // The value we are about to insert is closer to the next exemplar at the insertion point than what we calculated before in rIdx. + // v--rIdx + // |-----------x-----------n-x----------------x----x-----| + // new exemplar value--^ ^--nIdx + // Do not make the spread worse, replace nIdx-1 and not rIdx. + rIdx = nIdx + } + } + } + + // Adjust the slice according to rIdx and nIdx. + switch { + case rIdx == nIdx: + n.exemplars[nIdx] = e + case rIdx < nIdx: + n.exemplars = append(n.exemplars[:rIdx], append(n.exemplars[rIdx+1:nIdx], append([]*dto.Exemplar{e}, n.exemplars[nIdx:]...)...)...) + case rIdx > nIdx: + n.exemplars = append(n.exemplars[:nIdx], append([]*dto.Exemplar{e}, append(n.exemplars[nIdx:rIdx], n.exemplars[rIdx+1:]...)...)...) + } +} + +type constNativeHistogram struct { + desc *Desc + dto.Histogram + labelPairs []*dto.LabelPair +} + +func validateCount(sum float64, count uint64, negativeBuckets, positiveBuckets map[int]int64, zeroBucket uint64) error { + var bucketPopulationSum int64 + for _, v := range positiveBuckets { + bucketPopulationSum += v + } + for _, v := range negativeBuckets { + bucketPopulationSum += v + } + bucketPopulationSum += int64(zeroBucket) + + // If the sum of observations is NaN, the number of observations must be greater or equal to the sum of all bucket counts. + // Otherwise, the number of observations must be equal to the sum of all bucket counts . + + if math.IsNaN(sum) && bucketPopulationSum > int64(count) || + !math.IsNaN(sum) && bucketPopulationSum != int64(count) { + return errors.New("the sum of all bucket populations exceeds the count of observations") + } + return nil +} + +// NewConstNativeHistogram returns a metric representing a Prometheus native histogram with +// fixed values for the count, sum, and positive/negative/zero bucket counts. As those parameters +// cannot be changed, the returned value does not implement the Histogram +// interface (but only the Metric interface). Users of this package will not +// have much use for it in regular operations. However, when implementing custom +// OpenTelemetry Collectors, it is useful as a throw-away metric that is generated on the fly +// to send it to Prometheus in the Collect method. +// +// zeroBucket counts all (positive and negative) +// observations in the zero bucket (with an absolute value less or equal +// the current threshold). +// positiveBuckets and negativeBuckets are separate maps for negative and positive +// observations. The map's value is an int64, counting observations in +// that bucket. The map's key is the +// index of the bucket according to the used +// Schema. Index 0 is for an upper bound of 1 in positive buckets and for a lower bound of -1 in negative buckets. +// NewConstNativeHistogram returns an error if +// - the length of labelValues is not consistent with the variable labels in Desc or if Desc is invalid. +// - the schema passed is not between 8 and -4 +// - the sum of counts in all buckets including the zero bucket does not equal the count if sum is not NaN (or exceeds the count if sum is NaN) +// +// See https://opentelemetry.io/docs/specs/otel/compatibility/prometheus_and_openmetrics/#exponential-histograms for more details about the conversion from OTel to Prometheus. +func NewConstNativeHistogram( + desc *Desc, + count uint64, + sum float64, + positiveBuckets, negativeBuckets map[int]int64, + zeroBucket uint64, + schema int32, + zeroThreshold float64, + createdTimestamp time.Time, + labelValues ...string, +) (Metric, error) { + if desc.err != nil { + return nil, desc.err + } + if err := validateLabelValues(labelValues, len(desc.variableLabels.names)); err != nil { + return nil, err + } + if schema > nativeHistogramSchemaMaximum || schema < nativeHistogramSchemaMinimum { + return nil, errors.New("invalid native histogram schema") + } + if err := validateCount(sum, count, negativeBuckets, positiveBuckets, zeroBucket); err != nil { + return nil, err + } + + NegativeSpan, NegativeDelta := makeBucketsFromMap(negativeBuckets) + PositiveSpan, PositiveDelta := makeBucketsFromMap(positiveBuckets) + ret := &constNativeHistogram{ + desc: desc, + Histogram: dto.Histogram{ + CreatedTimestamp: timestamppb.New(createdTimestamp), + Schema: &schema, + ZeroThreshold: &zeroThreshold, + SampleCount: &count, + SampleSum: &sum, + + NegativeSpan: NegativeSpan, + NegativeDelta: NegativeDelta, + + PositiveSpan: PositiveSpan, + PositiveDelta: PositiveDelta, + + ZeroCount: proto.Uint64(zeroBucket), + }, + labelPairs: MakeLabelPairs(desc, labelValues), + } + if *ret.ZeroThreshold == 0 && *ret.ZeroCount == 0 && len(ret.PositiveSpan) == 0 && len(ret.NegativeSpan) == 0 { + ret.PositiveSpan = []*dto.BucketSpan{{ + Offset: proto.Int32(0), + Length: proto.Uint32(0), + }} + } + return ret, nil +} + +// MustNewConstNativeHistogram is a version of NewConstNativeHistogram that panics where +// NewConstNativeHistogram would have returned an error. +func MustNewConstNativeHistogram( + desc *Desc, + count uint64, + sum float64, + positiveBuckets, negativeBuckets map[int]int64, + zeroBucket uint64, + nativeHistogramSchema int32, + nativeHistogramZeroThreshold float64, + createdTimestamp time.Time, + labelValues ...string, +) Metric { + nativehistogram, err := NewConstNativeHistogram(desc, + count, + sum, + positiveBuckets, + negativeBuckets, + zeroBucket, + nativeHistogramSchema, + nativeHistogramZeroThreshold, + createdTimestamp, + labelValues...) + if err != nil { + panic(err) + } + return nativehistogram +} + +func (h *constNativeHistogram) Desc() *Desc { + return h.desc +} + +func (h *constNativeHistogram) Write(out *dto.Metric) error { + out.Histogram = &h.Histogram + out.Label = h.labelPairs + return nil +} + +func makeBucketsFromMap(buckets map[int]int64) ([]*dto.BucketSpan, []int64) { + if len(buckets) == 0 { + return nil, nil + } + var ii []int + for k := range buckets { + ii = append(ii, k) + } + sort.Ints(ii) + + var ( + spans []*dto.BucketSpan + deltas []int64 + prevCount int64 + nextI int + ) + + appendDelta := func(count int64) { + *spans[len(spans)-1].Length++ + deltas = append(deltas, count-prevCount) + prevCount = count + } + + for n, i := range ii { + count := buckets[i] + // Multiple spans with only small gaps in between are probably + // encoded more efficiently as one larger span with a few empty + // buckets. Needs some research to find the sweet spot. For now, + // we assume that gaps of one or two buckets should not create + // a new span. + iDelta := int32(i - nextI) + if n == 0 || iDelta > 2 { + // We have to create a new span, either because we are + // at the very beginning, or because we have found a gap + // of more than two buckets. + spans = append(spans, &dto.BucketSpan{ + Offset: proto.Int32(iDelta), + Length: proto.Uint32(0), + }) + } else { + // We have found a small gap (or no gap at all). + // Insert empty buckets as needed. + for j := int32(0); j < iDelta; j++ { + appendDelta(0) + } + } + appendDelta(count) + nextI = i + 1 + } + return spans, deltas +} diff --git a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/internal/difflib.go b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/internal/difflib.go index a595a20362..8b016355ad 100644 --- a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/internal/difflib.go +++ b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/internal/difflib.go @@ -22,17 +22,18 @@ import ( "bytes" "fmt" "io" + "strconv" "strings" ) -func min(a, b int) int { +func minInt(a, b int) int { if a < b { return a } return b } -func max(a, b int) int { +func maxInt(a, b int) int { if a > b { return a } @@ -427,12 +428,12 @@ func (m *SequenceMatcher) GetGroupedOpCodes(n int) [][]OpCode { if codes[0].Tag == 'e' { c := codes[0] i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 - codes[0] = OpCode{c.Tag, max(i1, i2-n), i2, max(j1, j2-n), j2} + codes[0] = OpCode{c.Tag, maxInt(i1, i2-n), i2, maxInt(j1, j2-n), j2} } if codes[len(codes)-1].Tag == 'e' { c := codes[len(codes)-1] i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 - codes[len(codes)-1] = OpCode{c.Tag, i1, min(i2, i1+n), j1, min(j2, j1+n)} + codes[len(codes)-1] = OpCode{c.Tag, i1, minInt(i2, i1+n), j1, minInt(j2, j1+n)} } nn := n + n groups := [][]OpCode{} @@ -443,12 +444,12 @@ func (m *SequenceMatcher) GetGroupedOpCodes(n int) [][]OpCode { // there is a large range with no changes. if c.Tag == 'e' && i2-i1 > nn { group = append(group, OpCode{ - c.Tag, i1, min(i2, i1+n), - j1, min(j2, j1+n), + c.Tag, i1, minInt(i2, i1+n), + j1, minInt(j2, j1+n), }) groups = append(groups, group) group = []OpCode{} - i1, j1 = max(i1, i2-n), max(j1, j2-n) + i1, j1 = maxInt(i1, i2-n), maxInt(j1, j2-n) } group = append(group, OpCode{c.Tag, i1, i2, j1, j2}) } @@ -515,7 +516,7 @@ func (m *SequenceMatcher) QuickRatio() float64 { // is faster to compute than either .Ratio() or .QuickRatio(). func (m *SequenceMatcher) RealQuickRatio() float64 { la, lb := len(m.a), len(m.b) - return calculateRatio(min(la, lb), la+lb) + return calculateRatio(minInt(la, lb), la+lb) } // Convert range to the "ed" format @@ -524,7 +525,7 @@ func formatRangeUnified(start, stop int) string { beginning := start + 1 // lines start numbering with one length := stop - start if length == 1 { - return fmt.Sprintf("%d", beginning) + return strconv.Itoa(beginning) } if length == 0 { beginning-- // empty ranges begin at line just before the range diff --git a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/internal/go_collector_options.go b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/internal/go_collector_options.go index 723b45d644..a4fa6eabd7 100644 --- a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/internal/go_collector_options.go +++ b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/internal/go_collector_options.go @@ -30,3 +30,5 @@ type GoCollectorOptions struct { RuntimeMetricSumForHist map[string]string RuntimeMetricRules []GoCollectorRule } + +var GoCollectorDefaultRuntimeMetrics = regexp.MustCompile(`/gc/gogc:percent|/gc/gomemlimit:bytes|/sched/gomaxprocs:threads`) diff --git a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/internal/go_runtime_metrics.go b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/internal/go_runtime_metrics.go index 97d17d6cb6..f7f97ef926 100644 --- a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/internal/go_runtime_metrics.go +++ b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/internal/go_runtime_metrics.go @@ -66,7 +66,8 @@ func RuntimeMetricsToProm(d *metrics.Description) (string, string, string, bool) name += "_total" } - valid := model.IsValidMetricName(model.LabelValue(namespace + "_" + subsystem + "_" + name)) + // Our current conversion moves to legacy naming, so use legacy validation. + valid := model.IsValidLegacyMetricName(namespace + "_" + subsystem + "_" + name) switch d.Kind { case metrics.KindUint64: case metrics.KindFloat64: diff --git a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/metric.go b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/metric.go index f018e57237..592eec3e24 100644 --- a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/metric.go +++ b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/metric.go @@ -108,15 +108,23 @@ func BuildFQName(namespace, subsystem, name string) string { if name == "" { return "" } - switch { - case namespace != "" && subsystem != "": - return strings.Join([]string{namespace, subsystem, name}, "_") - case namespace != "": - return strings.Join([]string{namespace, name}, "_") - case subsystem != "": - return strings.Join([]string{subsystem, name}, "_") + + sb := strings.Builder{} + sb.Grow(len(namespace) + len(subsystem) + len(name) + 2) + + if namespace != "" { + sb.WriteString(namespace) + sb.WriteString("_") } - return name + + if subsystem != "" { + sb.WriteString(subsystem) + sb.WriteString("_") + } + + sb.WriteString(name) + + return sb.String() } type invalidMetric struct { @@ -234,7 +242,7 @@ func NewMetricWithExemplars(m Metric, exemplars ...Exemplar) (Metric, error) { ) for i, e := range exemplars { ts := e.Timestamp - if ts == (time.Time{}) { + if ts.IsZero() { ts = now } exs[i], err = newExemplar(e.Value, ts, e.Labels) diff --git a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/process_collector.go b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/process_collector.go index 8548dd18ed..e7bce8b58e 100644 --- a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/process_collector.go +++ b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/process_collector.go @@ -22,14 +22,16 @@ import ( ) type processCollector struct { - collectFn func(chan<- Metric) - pidFn func() (int, error) - reportErrors bool - cpuTotal *Desc - openFDs, maxFDs *Desc - vsize, maxVsize *Desc - rss *Desc - startTime *Desc + collectFn func(chan<- Metric) + describeFn func(chan<- *Desc) + pidFn func() (int, error) + reportErrors bool + cpuTotal *Desc + openFDs, maxFDs *Desc + vsize, maxVsize *Desc + rss *Desc + startTime *Desc + inBytes, outBytes *Desc } // ProcessCollectorOpts defines the behavior of a process metrics collector @@ -100,6 +102,16 @@ func NewProcessCollector(opts ProcessCollectorOpts) Collector { "Start time of the process since unix epoch in seconds.", nil, nil, ), + inBytes: NewDesc( + ns+"process_network_receive_bytes_total", + "Number of bytes received by the process over the network.", + nil, nil, + ), + outBytes: NewDesc( + ns+"process_network_transmit_bytes_total", + "Number of bytes sent by the process over the network.", + nil, nil, + ), } if opts.PidFn == nil { @@ -111,24 +123,23 @@ func NewProcessCollector(opts ProcessCollectorOpts) Collector { // Set up process metric collection if supported by the runtime. if canCollectProcess() { c.collectFn = c.processCollect + c.describeFn = c.describe } else { - c.collectFn = func(ch chan<- Metric) { - c.reportError(ch, nil, errors.New("process metrics not supported on this platform")) - } + c.collectFn = c.errorCollectFn + c.describeFn = c.errorDescribeFn } return c } -// Describe returns all descriptions of the collector. -func (c *processCollector) Describe(ch chan<- *Desc) { - ch <- c.cpuTotal - ch <- c.openFDs - ch <- c.maxFDs - ch <- c.vsize - ch <- c.maxVsize - ch <- c.rss - ch <- c.startTime +func (c *processCollector) errorCollectFn(ch chan<- Metric) { + c.reportError(ch, nil, errors.New("process metrics not supported on this platform")) +} + +func (c *processCollector) errorDescribeFn(ch chan<- *Desc) { + if c.reportErrors { + ch <- NewInvalidDesc(errors.New("process metrics not supported on this platform")) + } } // Collect returns the current state of all metrics of the collector. @@ -136,6 +147,11 @@ func (c *processCollector) Collect(ch chan<- Metric) { c.collectFn(ch) } +// Describe returns all descriptions of the collector. +func (c *processCollector) Describe(ch chan<- *Desc) { + c.describeFn(ch) +} + func (c *processCollector) reportError(ch chan<- Metric, desc *Desc, err error) { if !c.reportErrors { return diff --git a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/process_collector_darwin.go b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/process_collector_darwin.go new file mode 100644 index 0000000000..0a61b98461 --- /dev/null +++ b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/process_collector_darwin.go @@ -0,0 +1,130 @@ +// Copyright 2024 The Prometheus Authors +// 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. + +//go:build darwin && !ios + +package prometheus + +import ( + "errors" + "fmt" + "os" + "syscall" + "time" + + "golang.org/x/sys/unix" +) + +// notImplementedErr is returned by stub functions that replace cgo functions, when cgo +// isn't available. +var notImplementedErr = errors.New("not implemented") + +type memoryInfo struct { + vsize uint64 // Virtual memory size in bytes + rss uint64 // Resident memory size in bytes +} + +func canCollectProcess() bool { + return true +} + +func getSoftLimit(which int) (uint64, error) { + rlimit := syscall.Rlimit{} + + if err := syscall.Getrlimit(which, &rlimit); err != nil { + return 0, err + } + + return rlimit.Cur, nil +} + +func getOpenFileCount() (float64, error) { + // Alternately, the undocumented proc_pidinfo(PROC_PIDLISTFDS) can be used to + // return a list of open fds, but that requires a way to call C APIs. The + // benefits, however, include fewer system calls and not failing when at the + // open file soft limit. + + if dir, err := os.Open("/dev/fd"); err != nil { + return 0.0, err + } else { + defer dir.Close() + + // Avoid ReadDir(), as it calls stat(2) on each descriptor. Not only is + // that info not used, but KQUEUE descriptors fail stat(2), which causes + // the whole method to fail. + if names, err := dir.Readdirnames(0); err != nil { + return 0.0, err + } else { + // Subtract 1 to ignore the open /dev/fd descriptor above. + return float64(len(names) - 1), nil + } + } +} + +func (c *processCollector) processCollect(ch chan<- Metric) { + if procs, err := unix.SysctlKinfoProcSlice("kern.proc.pid", os.Getpid()); err == nil { + if len(procs) == 1 { + startTime := float64(procs[0].Proc.P_starttime.Nano() / 1e9) + ch <- MustNewConstMetric(c.startTime, GaugeValue, startTime) + } else { + err = fmt.Errorf("sysctl() returned %d proc structs (expected 1)", len(procs)) + c.reportError(ch, c.startTime, err) + } + } else { + c.reportError(ch, c.startTime, err) + } + + // The proc structure returned by kern.proc.pid above has an Rusage member, + // but it is not filled in, so it needs to be fetched by getrusage(2). For + // that call, the UTime, STime, and Maxrss members are filled out, but not + // Ixrss, Idrss, or Isrss for the memory usage. Memory stats will require + // access to the C API to call task_info(TASK_BASIC_INFO). + rusage := unix.Rusage{} + + if err := unix.Getrusage(syscall.RUSAGE_SELF, &rusage); err == nil { + cpuTime := time.Duration(rusage.Stime.Nano() + rusage.Utime.Nano()).Seconds() + ch <- MustNewConstMetric(c.cpuTotal, CounterValue, cpuTime) + } else { + c.reportError(ch, c.cpuTotal, err) + } + + if memInfo, err := getMemory(); err == nil { + ch <- MustNewConstMetric(c.rss, GaugeValue, float64(memInfo.rss)) + ch <- MustNewConstMetric(c.vsize, GaugeValue, float64(memInfo.vsize)) + } else if !errors.Is(err, notImplementedErr) { + // Don't report an error when support is not compiled in. + c.reportError(ch, c.rss, err) + c.reportError(ch, c.vsize, err) + } + + if fds, err := getOpenFileCount(); err == nil { + ch <- MustNewConstMetric(c.openFDs, GaugeValue, fds) + } else { + c.reportError(ch, c.openFDs, err) + } + + if openFiles, err := getSoftLimit(syscall.RLIMIT_NOFILE); err == nil { + ch <- MustNewConstMetric(c.maxFDs, GaugeValue, float64(openFiles)) + } else { + c.reportError(ch, c.maxFDs, err) + } + + if addressSpace, err := getSoftLimit(syscall.RLIMIT_AS); err == nil { + ch <- MustNewConstMetric(c.maxVsize, GaugeValue, float64(addressSpace)) + } else { + c.reportError(ch, c.maxVsize, err) + } + + // TODO: socket(PF_SYSTEM) to fetch "com.apple.network.statistics" might + // be able to get the per-process network send/receive counts. +} diff --git a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/process_collector_mem_cgo_darwin.c b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/process_collector_mem_cgo_darwin.c new file mode 100644 index 0000000000..d00a24315d --- /dev/null +++ b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/process_collector_mem_cgo_darwin.c @@ -0,0 +1,84 @@ +// Copyright 2024 The Prometheus Authors +// 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. + +//go:build darwin && !ios && cgo + +#include +#include +#include + +// The compiler warns that mach/shared_memory_server.h is deprecated, and to use +// mach/shared_region.h instead. But that doesn't define +// SHARED_DATA_REGION_SIZE or SHARED_TEXT_REGION_SIZE, so redefine them here and +// avoid a warning message when running tests. +#define GLOBAL_SHARED_TEXT_SEGMENT 0x90000000U +#define SHARED_DATA_REGION_SIZE 0x10000000 +#define SHARED_TEXT_REGION_SIZE 0x10000000 + + +int get_memory_info(unsigned long long *rss, unsigned long long *vsize) +{ + // This is lightly adapted from how ps(1) obtains its memory info. + // https://github.com/apple-oss-distributions/adv_cmds/blob/8744084ea0ff41ca4bb96b0f9c22407d0e48e9b7/ps/tasks.c#L109 + + kern_return_t error; + task_t task = MACH_PORT_NULL; + mach_task_basic_info_data_t info; + mach_msg_type_number_t info_count = MACH_TASK_BASIC_INFO_COUNT; + + error = task_info( + mach_task_self(), + MACH_TASK_BASIC_INFO, + (task_info_t) &info, + &info_count ); + + if( error != KERN_SUCCESS ) + { + return error; + } + + *rss = info.resident_size; + *vsize = info.virtual_size; + + { + vm_region_basic_info_data_64_t b_info; + mach_vm_address_t address = GLOBAL_SHARED_TEXT_SEGMENT; + mach_vm_size_t size; + mach_port_t object_name; + + /* + * try to determine if this task has the split libraries + * mapped in... if so, adjust its virtual size down by + * the 2 segments that are used for split libraries + */ + info_count = VM_REGION_BASIC_INFO_COUNT_64; + + error = mach_vm_region( + mach_task_self(), + &address, + &size, + VM_REGION_BASIC_INFO_64, + (vm_region_info_t) &b_info, + &info_count, + &object_name); + + if (error == KERN_SUCCESS) { + if (b_info.reserved && size == (SHARED_TEXT_REGION_SIZE) && + *vsize > (SHARED_TEXT_REGION_SIZE + SHARED_DATA_REGION_SIZE)) { + *vsize -= (SHARED_TEXT_REGION_SIZE + SHARED_DATA_REGION_SIZE); + } + } + } + + return 0; +} diff --git a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/process_collector_mem_cgo_darwin.go b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/process_collector_mem_cgo_darwin.go new file mode 100644 index 0000000000..9ac53f9992 --- /dev/null +++ b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/process_collector_mem_cgo_darwin.go @@ -0,0 +1,51 @@ +// Copyright 2024 The Prometheus Authors +// 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. + +//go:build darwin && !ios && cgo + +package prometheus + +/* +int get_memory_info(unsigned long long *rss, unsigned long long *vs); +*/ +import "C" +import "fmt" + +func getMemory() (*memoryInfo, error) { + var rss, vsize C.ulonglong + + if err := C.get_memory_info(&rss, &vsize); err != 0 { + return nil, fmt.Errorf("task_info() failed with 0x%x", int(err)) + } + + return &memoryInfo{vsize: uint64(vsize), rss: uint64(rss)}, nil +} + +// describe returns all descriptions of the collector for Darwin. +// Ensure that this list of descriptors is kept in sync with the metrics collected +// in the processCollect method. Any changes to the metrics in processCollect +// (such as adding or removing metrics) should be reflected in this list of descriptors. +func (c *processCollector) describe(ch chan<- *Desc) { + ch <- c.cpuTotal + ch <- c.openFDs + ch <- c.maxFDs + ch <- c.maxVsize + ch <- c.startTime + ch <- c.rss + ch <- c.vsize + + /* the process could be collected but not implemented yet + ch <- c.inBytes + ch <- c.outBytes + */ +} diff --git a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/process_collector_mem_nocgo_darwin.go b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/process_collector_mem_nocgo_darwin.go new file mode 100644 index 0000000000..8ddb0995d6 --- /dev/null +++ b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/process_collector_mem_nocgo_darwin.go @@ -0,0 +1,39 @@ +// Copyright 2024 The Prometheus Authors +// 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. + +//go:build darwin && !ios && !cgo + +package prometheus + +func getMemory() (*memoryInfo, error) { + return nil, notImplementedErr +} + +// describe returns all descriptions of the collector for Darwin. +// Ensure that this list of descriptors is kept in sync with the metrics collected +// in the processCollect method. Any changes to the metrics in processCollect +// (such as adding or removing metrics) should be reflected in this list of descriptors. +func (c *processCollector) describe(ch chan<- *Desc) { + ch <- c.cpuTotal + ch <- c.openFDs + ch <- c.maxFDs + ch <- c.maxVsize + ch <- c.startTime + + /* the process could be collected but not implemented yet + ch <- c.rss + ch <- c.vsize + ch <- c.inBytes + ch <- c.outBytes + */ +} diff --git a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/process_collector_wasip1.go b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/process_collector_not_supported.go similarity index 55% rename from go-controller/vendor/github.com/prometheus/client_golang/prometheus/process_collector_wasip1.go rename to go-controller/vendor/github.com/prometheus/client_golang/prometheus/process_collector_not_supported.go index d8d9a6d7a2..7732b7f376 100644 --- a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/process_collector_wasip1.go +++ b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/process_collector_not_supported.go @@ -11,8 +11,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:build wasip1 -// +build wasip1 +//go:build wasip1 || js || ios +// +build wasip1 js ios package prometheus @@ -20,7 +20,14 @@ func canCollectProcess() bool { return false } -func (*processCollector) processCollect(chan<- Metric) { - // noop on this platform - return +func (c *processCollector) processCollect(ch chan<- Metric) { + c.errorCollectFn(ch) +} + +// describe returns all descriptions of the collector for wasip1 and js. +// Ensure that this list of descriptors is kept in sync with the metrics collected +// in the processCollect method. Any changes to the metrics in processCollect +// (such as adding or removing metrics) should be reflected in this list of descriptors. +func (c *processCollector) describe(ch chan<- *Desc) { + c.errorDescribeFn(ch) } diff --git a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/process_collector_other.go b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/process_collector_procfsenabled.go similarity index 63% rename from go-controller/vendor/github.com/prometheus/client_golang/prometheus/process_collector_other.go rename to go-controller/vendor/github.com/prometheus/client_golang/prometheus/process_collector_procfsenabled.go index 8c1136ceea..9f4b130bef 100644 --- a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/process_collector_other.go +++ b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/process_collector_procfsenabled.go @@ -11,8 +11,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:build !windows && !js && !wasip1 -// +build !windows,!js,!wasip1 +//go:build !windows && !js && !wasip1 && !darwin +// +build !windows,!js,!wasip1,!darwin package prometheus @@ -63,4 +63,34 @@ func (c *processCollector) processCollect(ch chan<- Metric) { } else { c.reportError(ch, nil, err) } + + if netstat, err := p.Netstat(); err == nil { + var inOctets, outOctets float64 + if netstat.IpExt.InOctets != nil { + inOctets = *netstat.IpExt.InOctets + } + if netstat.IpExt.OutOctets != nil { + outOctets = *netstat.IpExt.OutOctets + } + ch <- MustNewConstMetric(c.inBytes, CounterValue, inOctets) + ch <- MustNewConstMetric(c.outBytes, CounterValue, outOctets) + } else { + c.reportError(ch, nil, err) + } +} + +// describe returns all descriptions of the collector for others than windows, js, wasip1 and darwin. +// Ensure that this list of descriptors is kept in sync with the metrics collected +// in the processCollect method. Any changes to the metrics in processCollect +// (such as adding or removing metrics) should be reflected in this list of descriptors. +func (c *processCollector) describe(ch chan<- *Desc) { + ch <- c.cpuTotal + ch <- c.openFDs + ch <- c.maxFDs + ch <- c.vsize + ch <- c.maxVsize + ch <- c.rss + ch <- c.startTime + ch <- c.inBytes + ch <- c.outBytes } diff --git a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/process_collector_windows.go b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/process_collector_windows.go index f973398df2..fa474289ef 100644 --- a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/process_collector_windows.go +++ b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/process_collector_windows.go @@ -79,14 +79,10 @@ func getProcessHandleCount(handle windows.Handle) (uint32, error) { } func (c *processCollector) processCollect(ch chan<- Metric) { - h, err := windows.GetCurrentProcess() - if err != nil { - c.reportError(ch, nil, err) - return - } + h := windows.CurrentProcess() var startTime, exitTime, kernelTime, userTime windows.Filetime - err = windows.GetProcessTimes(h, &startTime, &exitTime, &kernelTime, &userTime) + err := windows.GetProcessTimes(h, &startTime, &exitTime, &kernelTime, &userTime) if err != nil { c.reportError(ch, nil, err) return @@ -111,6 +107,19 @@ func (c *processCollector) processCollect(ch chan<- Metric) { ch <- MustNewConstMetric(c.maxFDs, GaugeValue, float64(16*1024*1024)) // Windows has a hard-coded max limit, not per-process. } +// describe returns all descriptions of the collector for windows. +// Ensure that this list of descriptors is kept in sync with the metrics collected +// in the processCollect method. Any changes to the metrics in processCollect +// (such as adding or removing metrics) should be reflected in this list of descriptors. +func (c *processCollector) describe(ch chan<- *Desc) { + ch <- c.cpuTotal + ch <- c.openFDs + ch <- c.maxFDs + ch <- c.vsize + ch <- c.rss + ch <- c.startTime +} + func fileTimeToSeconds(ft windows.Filetime) float64 { return float64(uint64(ft.HighDateTime)<<32+uint64(ft.LowDateTime)) / 1e7 } diff --git a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator.go b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator.go index 9819917b83..315eab5f17 100644 --- a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator.go +++ b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator.go @@ -76,6 +76,12 @@ func (r *responseWriterDelegator) Write(b []byte) (int, error) { return n, err } +// Unwrap lets http.ResponseController get the underlying http.ResponseWriter, +// by implementing the [rwUnwrapper](https://cs.opensource.google/go/go/+/refs/tags/go1.21.4:src/net/http/responsecontroller.go;l=42-44) interface. +func (r *responseWriterDelegator) Unwrap() http.ResponseWriter { + return r.ResponseWriter +} + type ( closeNotifierDelegator struct{ *responseWriterDelegator } flusherDelegator struct{ *responseWriterDelegator } diff --git a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go index 09b8d2fbea..763d99e362 100644 --- a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go +++ b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go @@ -38,13 +38,14 @@ import ( "io" "net/http" "strconv" - "strings" "sync" "time" "github.com/prometheus/common/expfmt" + "github.com/prometheus/client_golang/internal/github.com/golang/gddo/httputil" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promhttp/internal" ) const ( @@ -54,6 +55,24 @@ const ( processStartTimeHeader = "Process-Start-Time-Unix" ) +// Compression represents the content encodings handlers support for the HTTP +// responses. +type Compression string + +const ( + Identity Compression = "identity" + Gzip Compression = "gzip" + Zstd Compression = "zstd" +) + +func defaultCompressionFormats() []Compression { + if internal.NewZstdWriter != nil { + return []Compression{Identity, Gzip, Zstd} + } else { + return []Compression{Identity, Gzip} + } +} + var gzipPool = sync.Pool{ New: func() interface{} { return gzip.NewWriter(nil) @@ -122,6 +141,18 @@ func HandlerForTransactional(reg prometheus.TransactionalGatherer, opts HandlerO } } + // Select compression formats to offer based on default or user choice. + var compressions []string + if !opts.DisableCompression { + offers := defaultCompressionFormats() + if len(opts.OfferedCompressions) > 0 { + offers = opts.OfferedCompressions + } + for _, comp := range offers { + compressions = append(compressions, string(comp)) + } + } + h := http.HandlerFunc(func(rsp http.ResponseWriter, req *http.Request) { if !opts.ProcessStartTime.IsZero() { rsp.Header().Set(processStartTimeHeader, strconv.FormatInt(opts.ProcessStartTime.Unix(), 10)) @@ -165,22 +196,30 @@ func HandlerForTransactional(reg prometheus.TransactionalGatherer, opts HandlerO } else { contentType = expfmt.Negotiate(req.Header) } - header := rsp.Header() - header.Set(contentTypeHeader, string(contentType)) + rsp.Header().Set(contentTypeHeader, string(contentType)) - w := io.Writer(rsp) - if !opts.DisableCompression && gzipAccepted(req.Header) { - header.Set(contentEncodingHeader, "gzip") - gz := gzipPool.Get().(*gzip.Writer) - defer gzipPool.Put(gz) + w, encodingHeader, closeWriter, err := negotiateEncodingWriter(req, rsp, compressions) + if err != nil { + if opts.ErrorLog != nil { + opts.ErrorLog.Println("error getting writer", err) + } + w = io.Writer(rsp) + encodingHeader = string(Identity) + } - gz.Reset(w) - defer gz.Close() + defer closeWriter() - w = gz + // Set Content-Encoding only when data is compressed + if encodingHeader != string(Identity) { + rsp.Header().Set(contentEncodingHeader, encodingHeader) } - enc := expfmt.NewEncoder(w, contentType) + var enc expfmt.Encoder + if opts.EnableOpenMetricsTextCreatedSamples { + enc = expfmt.NewEncoder(w, contentType, expfmt.WithCreatedLines()) + } else { + enc = expfmt.NewEncoder(w, contentType) + } // handleError handles the error according to opts.ErrorHandling // and returns true if we have to abort after the handling. @@ -343,9 +382,19 @@ type HandlerOpts struct { // no effect on the HTTP status code because ErrorHandling is set to // ContinueOnError. Registry prometheus.Registerer - // If DisableCompression is true, the handler will never compress the - // response, even if requested by the client. + // DisableCompression disables the response encoding (compression) and + // encoding negotiation. If true, the handler will + // never compress the response, even if requested + // by the client and the OfferedCompressions field is set. DisableCompression bool + // OfferedCompressions is a set of encodings (compressions) handler will + // try to offer when negotiating with the client. This defaults to identity, gzip + // and zstd. + // NOTE: If handler can't agree with the client on the encodings or + // unsupported or empty encodings are set in OfferedCompressions, + // handler always fallbacks to no compression (identity), for + // compatibility reasons. In such cases ErrorLog will be used if set. + OfferedCompressions []Compression // The number of concurrent HTTP requests is limited to // MaxRequestsInFlight. Additional requests are responded to with 503 // Service Unavailable and a suitable message in the body. If @@ -371,6 +420,21 @@ type HandlerOpts struct { // (which changes the identity of the resulting series on the Prometheus // server). EnableOpenMetrics bool + // EnableOpenMetricsTextCreatedSamples specifies if this handler should add, extra, synthetic + // Created Timestamps for counters, histograms and summaries, which for the current + // version of OpenMetrics are defined as extra series with the same name and "_created" + // suffix. See also the OpenMetrics specification for more details + // https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md#counter-1 + // + // Created timestamps are used to improve the accuracy of reset detection, + // but the way it's designed in OpenMetrics 1.0 it also dramatically increases cardinality + // if the scraper does not handle those metrics correctly (converting to created timestamp + // instead of leaving those series as-is). New OpenMetrics versions might improve + // this situation. + // + // Prometheus introduced the feature flag 'created-timestamp-zero-ingestion' + // in version 2.50.0 to handle this situation. + EnableOpenMetricsTextCreatedSamples bool // ProcessStartTime allows setting process start timevalue that will be exposed // with "Process-Start-Time-Unix" response header along with the metrics // payload. This allow callers to have efficient transformations to cumulative @@ -381,19 +445,6 @@ type HandlerOpts struct { ProcessStartTime time.Time } -// gzipAccepted returns whether the client will accept gzip-encoded content. -func gzipAccepted(header http.Header) bool { - a := header.Get(acceptEncodingHeader) - parts := strings.Split(a, ",") - for _, part := range parts { - part = strings.TrimSpace(part) - if part == "gzip" || strings.HasPrefix(part, "gzip;") { - return true - } - } - return false -} - // httpError removes any content-encoding header and then calls http.Error with // the provided error and http.StatusInternalServerError. Error contents is // supposed to be uncompressed plain text. Same as with a plain http.Error, this @@ -406,3 +457,36 @@ func httpError(rsp http.ResponseWriter, err error) { http.StatusInternalServerError, ) } + +// negotiateEncodingWriter reads the Accept-Encoding header from a request and +// selects the right compression based on an allow-list of supported +// compressions. It returns a writer implementing the compression and an the +// correct value that the caller can set in the response header. +func negotiateEncodingWriter(r *http.Request, rw io.Writer, compressions []string) (_ io.Writer, encodingHeaderValue string, closeWriter func(), _ error) { + if len(compressions) == 0 { + return rw, string(Identity), func() {}, nil + } + + // TODO(mrueg): Replace internal/github.com/gddo once https://github.com/golang/go/issues/19307 is implemented. + selected := httputil.NegotiateContentEncoding(r, compressions) + + switch selected { + case "zstd": + if internal.NewZstdWriter == nil { + // The content encoding was not implemented yet. + return nil, "", func() {}, fmt.Errorf("content compression format not recognized: %s. Valid formats are: %s", selected, defaultCompressionFormats()) + } + writer, closeWriter, err := internal.NewZstdWriter(rw) + return writer, selected, closeWriter, err + case "gzip": + gz := gzipPool.Get().(*gzip.Writer) + gz.Reset(rw) + return gz, selected, func() { _ = gz.Close(); gzipPool.Put(gz) }, nil + case "identity": + // This means the content is not compressed. + return rw, selected, func() {}, nil + default: + // The content encoding was not implemented yet. + return nil, "", func() {}, fmt.Errorf("content compression format not recognized: %s. Valid formats are: %s", selected, defaultCompressionFormats()) + } +} diff --git a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/process_collector_js.go b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/promhttp/internal/compression.go similarity index 70% rename from go-controller/vendor/github.com/prometheus/client_golang/prometheus/process_collector_js.go rename to go-controller/vendor/github.com/prometheus/client_golang/prometheus/promhttp/internal/compression.go index b1e363d6cf..c5039590f7 100644 --- a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/process_collector_js.go +++ b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/promhttp/internal/compression.go @@ -1,4 +1,4 @@ -// Copyright 2019 The Prometheus Authors +// Copyright 2025 The Prometheus Authors // 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 @@ -11,16 +11,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:build js -// +build js +package internal -package prometheus +import ( + "io" +) -func canCollectProcess() bool { - return false -} - -func (c *processCollector) processCollect(ch chan<- Metric) { - // noop on this platform - return -} +// NewZstdWriter enables zstd write support if non-nil. +var NewZstdWriter func(rw io.Writer) (_ io.Writer, closeWriter func(), _ error) diff --git a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/registry.go b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/registry.go index 5e2ced25a0..c6fd2f58b7 100644 --- a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/registry.go +++ b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/registry.go @@ -314,16 +314,17 @@ func (r *Registry) Register(c Collector) error { if dimHash != desc.dimHash { return fmt.Errorf("a previously registered descriptor with the same fully-qualified name as %s has different label names or a different help string", desc) } - } else { - // ...then check the new descriptors already seen. - if dimHash, exists := newDimHashesByName[desc.fqName]; exists { - if dimHash != desc.dimHash { - return fmt.Errorf("descriptors reported by collector have inconsistent label names or help strings for the same fully-qualified name, offender is %s", desc) - } - } else { - newDimHashesByName[desc.fqName] = desc.dimHash + continue + } + + // ...then check the new descriptors already seen. + if dimHash, exists := newDimHashesByName[desc.fqName]; exists { + if dimHash != desc.dimHash { + return fmt.Errorf("descriptors reported by collector have inconsistent label names or help strings for the same fully-qualified name, offender is %s", desc) } + continue } + newDimHashesByName[desc.fqName] = desc.dimHash } // A Collector yielding no Desc at all is considered unchecked. if len(newDescIDs) == 0 { diff --git a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/summary.go b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/summary.go index 1462704446..ac5203c6fa 100644 --- a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/summary.go +++ b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/summary.go @@ -243,6 +243,7 @@ func newSummary(desc *Desc, opts SummaryOpts, labelValues ...string) Summary { s := &summary{ desc: desc, + now: opts.now, objectives: opts.Objectives, sortedObjectives: make([]float64, 0, len(opts.Objectives)), @@ -280,6 +281,8 @@ type summary struct { desc *Desc + now func() time.Time + objectives map[float64]float64 sortedObjectives []float64 @@ -307,7 +310,7 @@ func (s *summary) Observe(v float64) { s.bufMtx.Lock() defer s.bufMtx.Unlock() - now := time.Now() + now := s.now() if now.After(s.hotBufExpTime) { s.asyncFlush(now) } @@ -326,7 +329,7 @@ func (s *summary) Write(out *dto.Metric) error { s.bufMtx.Lock() s.mtx.Lock() // Swap bufs even if hotBuf is empty to set new hotBufExpTime. - s.swapBufs(time.Now()) + s.swapBufs(s.now()) s.bufMtx.Unlock() s.flushColdBuf() @@ -783,3 +786,45 @@ func MustNewConstSummary( } return m } + +// NewConstSummaryWithCreatedTimestamp does the same thing as NewConstSummary but sets the created timestamp. +func NewConstSummaryWithCreatedTimestamp( + desc *Desc, + count uint64, + sum float64, + quantiles map[float64]float64, + ct time.Time, + labelValues ...string, +) (Metric, error) { + if desc.err != nil { + return nil, desc.err + } + if err := validateLabelValues(labelValues, len(desc.variableLabels.names)); err != nil { + return nil, err + } + return &constSummary{ + desc: desc, + count: count, + sum: sum, + quantiles: quantiles, + labelPairs: MakeLabelPairs(desc, labelValues), + createdTs: timestamppb.New(ct), + }, nil +} + +// MustNewConstSummaryWithCreatedTimestamp is a version of NewConstSummaryWithCreatedTimestamp that panics where +// NewConstSummaryWithCreatedTimestamp would have returned an error. +func MustNewConstSummaryWithCreatedTimestamp( + desc *Desc, + count uint64, + sum float64, + quantiles map[float64]float64, + ct time.Time, + labelValues ...string, +) Metric { + m, err := NewConstSummaryWithCreatedTimestamp(desc, count, sum, quantiles, ct, labelValues...) + if err != nil { + panic(err) + } + return m +} diff --git a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/vec.go b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/vec.go index 955cfd59f8..2c808eece0 100644 --- a/go-controller/vendor/github.com/prometheus/client_golang/prometheus/vec.go +++ b/go-controller/vendor/github.com/prometheus/client_golang/prometheus/vec.go @@ -507,7 +507,7 @@ func (m *metricMap) getOrCreateMetricWithLabelValues( return metric } -// getOrCreateMetricWithLabelValues retrieves the metric by hash and label value +// getOrCreateMetricWithLabels retrieves the metric by hash and label value // or creates it and returns the new one. // // This function holds the mutex. diff --git a/go-controller/vendor/github.com/prometheus/common/expfmt/decode.go b/go-controller/vendor/github.com/prometheus/common/expfmt/decode.go index 25cfaa2164..1448439b7f 100644 --- a/go-controller/vendor/github.com/prometheus/common/expfmt/decode.go +++ b/go-controller/vendor/github.com/prometheus/common/expfmt/decode.go @@ -45,7 +45,7 @@ func ResponseFormat(h http.Header) Format { mediatype, params, err := mime.ParseMediaType(ct) if err != nil { - return fmtUnknown + return FmtUnknown } const textType = "text/plain" @@ -53,21 +53,21 @@ func ResponseFormat(h http.Header) Format { switch mediatype { case ProtoType: if p, ok := params["proto"]; ok && p != ProtoProtocol { - return fmtUnknown + return FmtUnknown } if e, ok := params["encoding"]; ok && e != "delimited" { - return fmtUnknown + return FmtUnknown } - return fmtProtoDelim + return FmtProtoDelim case textType: if v, ok := params["version"]; ok && v != TextVersion { - return fmtUnknown + return FmtUnknown } - return fmtText + return FmtText } - return fmtUnknown + return FmtUnknown } // NewDecoder returns a new decoder based on the given input format. diff --git a/go-controller/vendor/github.com/prometheus/common/expfmt/encode.go b/go-controller/vendor/github.com/prometheus/common/expfmt/encode.go index ff5ef7a9d9..d7f3d76f55 100644 --- a/go-controller/vendor/github.com/prometheus/common/expfmt/encode.go +++ b/go-controller/vendor/github.com/prometheus/common/expfmt/encode.go @@ -68,7 +68,7 @@ func Negotiate(h http.Header) Format { if escapeParam := ac.Params[model.EscapingKey]; escapeParam != "" { switch Format(escapeParam) { case model.AllowUTF8, model.EscapeUnderscores, model.EscapeDots, model.EscapeValues: - escapingScheme = Format(fmt.Sprintf("; escaping=%s", escapeParam)) + escapingScheme = Format("; escaping=" + escapeParam) default: // If the escaping parameter is unknown, ignore it. } @@ -77,18 +77,18 @@ func Negotiate(h http.Header) Format { if ac.Type+"/"+ac.SubType == ProtoType && ac.Params["proto"] == ProtoProtocol { switch ac.Params["encoding"] { case "delimited": - return fmtProtoDelim + escapingScheme + return FmtProtoDelim + escapingScheme case "text": - return fmtProtoText + escapingScheme + return FmtProtoText + escapingScheme case "compact-text": - return fmtProtoCompact + escapingScheme + return FmtProtoCompact + escapingScheme } } if ac.Type == "text" && ac.SubType == "plain" && (ver == TextVersion || ver == "") { - return fmtText + escapingScheme + return FmtText + escapingScheme } } - return fmtText + escapingScheme + return FmtText + escapingScheme } // NegotiateIncludingOpenMetrics works like Negotiate but includes @@ -101,7 +101,7 @@ func NegotiateIncludingOpenMetrics(h http.Header) Format { if escapeParam := ac.Params[model.EscapingKey]; escapeParam != "" { switch Format(escapeParam) { case model.AllowUTF8, model.EscapeUnderscores, model.EscapeDots, model.EscapeValues: - escapingScheme = Format(fmt.Sprintf("; escaping=%s", escapeParam)) + escapingScheme = Format("; escaping=" + escapeParam) default: // If the escaping parameter is unknown, ignore it. } @@ -110,26 +110,26 @@ func NegotiateIncludingOpenMetrics(h http.Header) Format { if ac.Type+"/"+ac.SubType == ProtoType && ac.Params["proto"] == ProtoProtocol { switch ac.Params["encoding"] { case "delimited": - return fmtProtoDelim + escapingScheme + return FmtProtoDelim + escapingScheme case "text": - return fmtProtoText + escapingScheme + return FmtProtoText + escapingScheme case "compact-text": - return fmtProtoCompact + escapingScheme + return FmtProtoCompact + escapingScheme } } if ac.Type == "text" && ac.SubType == "plain" && (ver == TextVersion || ver == "") { - return fmtText + escapingScheme + return FmtText + escapingScheme } if ac.Type+"/"+ac.SubType == OpenMetricsType && (ver == OpenMetricsVersion_0_0_1 || ver == OpenMetricsVersion_1_0_0 || ver == "") { switch ver { case OpenMetricsVersion_1_0_0: - return fmtOpenMetrics_1_0_0 + escapingScheme + return FmtOpenMetrics_1_0_0 + escapingScheme default: - return fmtOpenMetrics_0_0_1 + escapingScheme + return FmtOpenMetrics_0_0_1 + escapingScheme } } } - return fmtText + escapingScheme + return FmtText + escapingScheme } // NewEncoder returns a new encoder based on content type negotiation. All diff --git a/go-controller/vendor/github.com/prometheus/common/expfmt/expfmt.go b/go-controller/vendor/github.com/prometheus/common/expfmt/expfmt.go index 051b38cd17..b26886560d 100644 --- a/go-controller/vendor/github.com/prometheus/common/expfmt/expfmt.go +++ b/go-controller/vendor/github.com/prometheus/common/expfmt/expfmt.go @@ -15,7 +15,7 @@ package expfmt import ( - "fmt" + "errors" "strings" "github.com/prometheus/common/model" @@ -32,24 +32,31 @@ type Format string // it on the wire, new content-type strings will have to be agreed upon and // added here. const ( - TextVersion = "0.0.4" - ProtoType = `application/vnd.google.protobuf` - ProtoProtocol = `io.prometheus.client.MetricFamily` - protoFmt = ProtoType + "; proto=" + ProtoProtocol + ";" + TextVersion = "0.0.4" + ProtoType = `application/vnd.google.protobuf` + ProtoProtocol = `io.prometheus.client.MetricFamily` + // Deprecated: Use expfmt.NewFormat(expfmt.TypeProtoCompact) instead. + ProtoFmt = ProtoType + "; proto=" + ProtoProtocol + ";" OpenMetricsType = `application/openmetrics-text` OpenMetricsVersion_0_0_1 = "0.0.1" OpenMetricsVersion_1_0_0 = "1.0.0" - // The Content-Type values for the different wire protocols. Note that these - // values are now unexported. If code was relying on comparisons to these - // constants, instead use FormatType(). - fmtUnknown Format = `` - fmtText Format = `text/plain; version=` + TextVersion + `; charset=utf-8` - fmtProtoDelim Format = protoFmt + ` encoding=delimited` - fmtProtoText Format = protoFmt + ` encoding=text` - fmtProtoCompact Format = protoFmt + ` encoding=compact-text` - fmtOpenMetrics_1_0_0 Format = OpenMetricsType + `; version=` + OpenMetricsVersion_1_0_0 + `; charset=utf-8` - fmtOpenMetrics_0_0_1 Format = OpenMetricsType + `; version=` + OpenMetricsVersion_0_0_1 + `; charset=utf-8` + // The Content-Type values for the different wire protocols. Do not do direct + // comparisons to these constants, instead use the comparison functions. + // Deprecated: Use expfmt.NewFormat(expfmt.TypeUnknown) instead. + FmtUnknown Format = `` + // Deprecated: Use expfmt.NewFormat(expfmt.TypeTextPlain) instead. + FmtText Format = `text/plain; version=` + TextVersion + `; charset=utf-8` + // Deprecated: Use expfmt.NewFormat(expfmt.TypeProtoDelim) instead. + FmtProtoDelim Format = ProtoFmt + ` encoding=delimited` + // Deprecated: Use expfmt.NewFormat(expfmt.TypeProtoText) instead. + FmtProtoText Format = ProtoFmt + ` encoding=text` + // Deprecated: Use expfmt.NewFormat(expfmt.TypeProtoCompact) instead. + FmtProtoCompact Format = ProtoFmt + ` encoding=compact-text` + // Deprecated: Use expfmt.NewFormat(expfmt.TypeOpenMetrics) instead. + FmtOpenMetrics_1_0_0 Format = OpenMetricsType + `; version=` + OpenMetricsVersion_1_0_0 + `; charset=utf-8` + // Deprecated: Use expfmt.NewFormat(expfmt.TypeOpenMetrics) instead. + FmtOpenMetrics_0_0_1 Format = OpenMetricsType + `; version=` + OpenMetricsVersion_0_0_1 + `; charset=utf-8` ) const ( @@ -79,17 +86,17 @@ const ( func NewFormat(t FormatType) Format { switch t { case TypeProtoCompact: - return fmtProtoCompact + return FmtProtoCompact case TypeProtoDelim: - return fmtProtoDelim + return FmtProtoDelim case TypeProtoText: - return fmtProtoText + return FmtProtoText case TypeTextPlain: - return fmtText + return FmtText case TypeOpenMetrics: - return fmtOpenMetrics_1_0_0 + return FmtOpenMetrics_1_0_0 default: - return fmtUnknown + return FmtUnknown } } @@ -97,12 +104,35 @@ func NewFormat(t FormatType) Format { // specified version number. func NewOpenMetricsFormat(version string) (Format, error) { if version == OpenMetricsVersion_0_0_1 { - return fmtOpenMetrics_0_0_1, nil + return FmtOpenMetrics_0_0_1, nil } if version == OpenMetricsVersion_1_0_0 { - return fmtOpenMetrics_1_0_0, nil + return FmtOpenMetrics_1_0_0, nil } - return fmtUnknown, fmt.Errorf("unknown open metrics version string") + return FmtUnknown, errors.New("unknown open metrics version string") +} + +// WithEscapingScheme returns a copy of Format with the specified escaping +// scheme appended to the end. If an escaping scheme already exists it is +// removed. +func (f Format) WithEscapingScheme(s model.EscapingScheme) Format { + var terms []string + for _, p := range strings.Split(string(f), ";") { + toks := strings.Split(p, "=") + if len(toks) != 2 { + trimmed := strings.TrimSpace(p) + if len(trimmed) > 0 { + terms = append(terms, trimmed) + } + continue + } + key := strings.TrimSpace(toks[0]) + if key != model.EscapingKey { + terms = append(terms, strings.TrimSpace(p)) + } + } + terms = append(terms, model.EscapingKey+"="+s.String()) + return Format(strings.Join(terms, "; ")) } // FormatType deduces an overall FormatType for the given format. diff --git a/go-controller/vendor/github.com/prometheus/common/expfmt/openmetrics_create.go b/go-controller/vendor/github.com/prometheus/common/expfmt/openmetrics_create.go index 353c5e93f9..a21ed4ec1f 100644 --- a/go-controller/vendor/github.com/prometheus/common/expfmt/openmetrics_create.go +++ b/go-controller/vendor/github.com/prometheus/common/expfmt/openmetrics_create.go @@ -38,7 +38,7 @@ type EncoderOption func(*encoderOption) // WithCreatedLines is an EncoderOption that configures the OpenMetrics encoder // to include _created lines (See -// https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md#counter-1). +// https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md#counter-1). // Created timestamps can improve the accuracy of series reset detection, but // come with a bandwidth cost. // @@ -102,7 +102,7 @@ func WithUnit() EncoderOption { // // - According to the OM specs, the `# UNIT` line is optional, but if populated, // the unit has to be present in the metric name as its suffix: -// (see https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md#unit). +// (see https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md#unit). // However, in order to accommodate any potential scenario where such a change in the // metric name is not desirable, the users are here given the choice of either explicitly // opt in, in case they wish for the unit to be included in the output AND in the metric name @@ -152,8 +152,8 @@ func MetricFamilyToOpenMetrics(out io.Writer, in *dto.MetricFamily, options ...E if metricType == dto.MetricType_COUNTER && strings.HasSuffix(compliantName, "_total") { compliantName = name[:len(name)-6] } - if toOM.withUnit && in.Unit != nil && !strings.HasSuffix(compliantName, fmt.Sprintf("_%s", *in.Unit)) { - compliantName = compliantName + fmt.Sprintf("_%s", *in.Unit) + if toOM.withUnit && in.Unit != nil && !strings.HasSuffix(compliantName, "_"+*in.Unit) { + compliantName = compliantName + "_" + *in.Unit } // Comments, first HELP, then TYPE. @@ -477,7 +477,7 @@ func writeOpenMetricsNameAndLabelPairs( if name != "" { // If the name does not pass the legacy validity check, we must put the // metric name inside the braces, quoted. - if !model.IsValidLegacyMetricName(model.LabelValue(name)) { + if !model.IsValidLegacyMetricName(name) { metricInsideBraces = true err := w.WriteByte(separator) written++ diff --git a/go-controller/vendor/github.com/prometheus/common/expfmt/text_create.go b/go-controller/vendor/github.com/prometheus/common/expfmt/text_create.go index f9b8265a9e..4b86434b33 100644 --- a/go-controller/vendor/github.com/prometheus/common/expfmt/text_create.go +++ b/go-controller/vendor/github.com/prometheus/common/expfmt/text_create.go @@ -354,7 +354,7 @@ func writeNameAndLabelPairs( if name != "" { // If the name does not pass the legacy validity check, we must put the // metric name inside the braces. - if !model.IsValidLegacyMetricName(model.LabelValue(name)) { + if !model.IsValidLegacyMetricName(name) { metricInsideBraces = true err := w.WriteByte(separator) written++ @@ -498,7 +498,7 @@ func writeInt(w enhancedWriter, i int64) (int, error) { // writeName writes a string as-is if it complies with the legacy naming // scheme, or escapes it in double quotes if not. func writeName(w enhancedWriter, name string) (int, error) { - if model.IsValidLegacyMetricName(model.LabelValue(name)) { + if model.IsValidLegacyMetricName(name) { return w.WriteString(name) } var written int diff --git a/go-controller/vendor/github.com/prometheus/common/expfmt/text_parse.go b/go-controller/vendor/github.com/prometheus/common/expfmt/text_parse.go index 26490211af..b4607fe4d2 100644 --- a/go-controller/vendor/github.com/prometheus/common/expfmt/text_parse.go +++ b/go-controller/vendor/github.com/prometheus/common/expfmt/text_parse.go @@ -22,9 +22,9 @@ import ( "math" "strconv" "strings" + "unicode/utf8" dto "github.com/prometheus/client_model/go" - "google.golang.org/protobuf/proto" "github.com/prometheus/common/model" @@ -60,6 +60,7 @@ type TextParser struct { currentMF *dto.MetricFamily currentMetric *dto.Metric currentLabelPair *dto.LabelPair + currentLabelPairs []*dto.LabelPair // Temporarily stores label pairs while parsing a metric line. // The remaining member variables are only used for summaries/histograms. currentLabels map[string]string // All labels including '__name__' but excluding 'quantile'/'le' @@ -74,6 +75,9 @@ type TextParser struct { // count and sum of that summary/histogram. currentIsSummaryCount, currentIsSummarySum bool currentIsHistogramCount, currentIsHistogramSum bool + // These indicate if the metric name from the current line being parsed is inside + // braces and if that metric name was found respectively. + currentMetricIsInsideBraces, currentMetricInsideBracesIsPresent bool } // TextToMetricFamilies reads 'in' as the simple and flat text-based exchange @@ -137,12 +141,15 @@ func (p *TextParser) reset(in io.Reader) { } p.currentQuantile = math.NaN() p.currentBucket = math.NaN() + p.currentMF = nil } // startOfLine represents the state where the next byte read from p.buf is the // start of a line (or whitespace leading up to it). func (p *TextParser) startOfLine() stateFn { p.lineCount++ + p.currentMetricIsInsideBraces = false + p.currentMetricInsideBracesIsPresent = false if p.skipBlankTab(); p.err != nil { // This is the only place that we expect to see io.EOF, // which is not an error but the signal that we are done. @@ -158,6 +165,9 @@ func (p *TextParser) startOfLine() stateFn { return p.startComment case '\n': return p.startOfLine // Empty line, start the next one. + case '{': + p.currentMetricIsInsideBraces = true + return p.readingLabels } return p.readingMetricName } @@ -275,6 +285,8 @@ func (p *TextParser) startLabelName() stateFn { return nil // Unexpected end of input. } if p.currentByte == '}' { + p.currentMetric.Label = append(p.currentMetric.Label, p.currentLabelPairs...) + p.currentLabelPairs = nil if p.skipBlankTab(); p.err != nil { return nil // Unexpected end of input. } @@ -287,6 +299,45 @@ func (p *TextParser) startLabelName() stateFn { p.parseError(fmt.Sprintf("invalid label name for metric %q", p.currentMF.GetName())) return nil } + if p.skipBlankTabIfCurrentBlankTab(); p.err != nil { + return nil // Unexpected end of input. + } + if p.currentByte != '=' { + if p.currentMetricIsInsideBraces { + if p.currentMetricInsideBracesIsPresent { + p.parseError(fmt.Sprintf("multiple metric names for metric %q", p.currentMF.GetName())) + return nil + } + switch p.currentByte { + case ',': + p.setOrCreateCurrentMF() + if p.currentMF.Type == nil { + p.currentMF.Type = dto.MetricType_UNTYPED.Enum() + } + p.currentMetric = &dto.Metric{} + p.currentMetricInsideBracesIsPresent = true + return p.startLabelName + case '}': + p.setOrCreateCurrentMF() + if p.currentMF.Type == nil { + p.currentMF.Type = dto.MetricType_UNTYPED.Enum() + } + p.currentMetric = &dto.Metric{} + p.currentMetric.Label = append(p.currentMetric.Label, p.currentLabelPairs...) + p.currentLabelPairs = nil + if p.skipBlankTab(); p.err != nil { + return nil // Unexpected end of input. + } + return p.readingValue + default: + p.parseError(fmt.Sprintf("unexpected end of metric name %q", p.currentByte)) + return nil + } + } + p.parseError(fmt.Sprintf("expected '=' after label name, found %q", p.currentByte)) + p.currentLabelPairs = nil + return nil + } p.currentLabelPair = &dto.LabelPair{Name: proto.String(p.currentToken.String())} if p.currentLabelPair.GetName() == string(model.MetricNameLabel) { p.parseError(fmt.Sprintf("label name %q is reserved", model.MetricNameLabel)) @@ -296,23 +347,17 @@ func (p *TextParser) startLabelName() stateFn { // labels to 'real' labels. if !(p.currentMF.GetType() == dto.MetricType_SUMMARY && p.currentLabelPair.GetName() == model.QuantileLabel) && !(p.currentMF.GetType() == dto.MetricType_HISTOGRAM && p.currentLabelPair.GetName() == model.BucketLabel) { - p.currentMetric.Label = append(p.currentMetric.Label, p.currentLabelPair) - } - if p.skipBlankTabIfCurrentBlankTab(); p.err != nil { - return nil // Unexpected end of input. - } - if p.currentByte != '=' { - p.parseError(fmt.Sprintf("expected '=' after label name, found %q", p.currentByte)) - return nil + p.currentLabelPairs = append(p.currentLabelPairs, p.currentLabelPair) } // Check for duplicate label names. labels := make(map[string]struct{}) - for _, l := range p.currentMetric.Label { + for _, l := range p.currentLabelPairs { lName := l.GetName() if _, exists := labels[lName]; !exists { labels[lName] = struct{}{} } else { p.parseError(fmt.Sprintf("duplicate label names for metric %q", p.currentMF.GetName())) + p.currentLabelPairs = nil return nil } } @@ -345,6 +390,7 @@ func (p *TextParser) startLabelValue() stateFn { if p.currentQuantile, p.err = parseFloat(p.currentLabelPair.GetValue()); p.err != nil { // Create a more helpful error message. p.parseError(fmt.Sprintf("expected float as value for 'quantile' label, got %q", p.currentLabelPair.GetValue())) + p.currentLabelPairs = nil return nil } } else { @@ -371,12 +417,19 @@ func (p *TextParser) startLabelValue() stateFn { return p.startLabelName case '}': + if p.currentMF == nil { + p.parseError("invalid metric name") + return nil + } + p.currentMetric.Label = append(p.currentMetric.Label, p.currentLabelPairs...) + p.currentLabelPairs = nil if p.skipBlankTab(); p.err != nil { return nil // Unexpected end of input. } return p.readingValue default: p.parseError(fmt.Sprintf("unexpected end of label value %q", p.currentLabelPair.GetValue())) + p.currentLabelPairs = nil return nil } } @@ -585,6 +638,8 @@ func (p *TextParser) readTokenUntilNewline(recognizeEscapeSequence bool) { p.currentToken.WriteByte(p.currentByte) case 'n': p.currentToken.WriteByte('\n') + case '"': + p.currentToken.WriteByte('"') default: p.parseError(fmt.Sprintf("invalid escape sequence '\\%c'", p.currentByte)) return @@ -610,13 +665,45 @@ func (p *TextParser) readTokenUntilNewline(recognizeEscapeSequence bool) { // but not into p.currentToken. func (p *TextParser) readTokenAsMetricName() { p.currentToken.Reset() + // A UTF-8 metric name must be quoted and may have escaped characters. + quoted := false + escaped := false if !isValidMetricNameStart(p.currentByte) { return } - for { - p.currentToken.WriteByte(p.currentByte) + for p.err == nil { + if escaped { + switch p.currentByte { + case '\\': + p.currentToken.WriteByte(p.currentByte) + case 'n': + p.currentToken.WriteByte('\n') + case '"': + p.currentToken.WriteByte('"') + default: + p.parseError(fmt.Sprintf("invalid escape sequence '\\%c'", p.currentByte)) + return + } + escaped = false + } else { + switch p.currentByte { + case '"': + quoted = !quoted + if !quoted { + p.currentByte, p.err = p.buf.ReadByte() + return + } + case '\n': + p.parseError(fmt.Sprintf("metric name %q contains unescaped new-line", p.currentToken.String())) + return + case '\\': + escaped = true + default: + p.currentToken.WriteByte(p.currentByte) + } + } p.currentByte, p.err = p.buf.ReadByte() - if p.err != nil || !isValidMetricNameContinuation(p.currentByte) { + if !isValidMetricNameContinuation(p.currentByte, quoted) || (!quoted && p.currentByte == ' ') { return } } @@ -628,13 +715,45 @@ func (p *TextParser) readTokenAsMetricName() { // but not into p.currentToken. func (p *TextParser) readTokenAsLabelName() { p.currentToken.Reset() + // A UTF-8 label name must be quoted and may have escaped characters. + quoted := false + escaped := false if !isValidLabelNameStart(p.currentByte) { return } - for { - p.currentToken.WriteByte(p.currentByte) + for p.err == nil { + if escaped { + switch p.currentByte { + case '\\': + p.currentToken.WriteByte(p.currentByte) + case 'n': + p.currentToken.WriteByte('\n') + case '"': + p.currentToken.WriteByte('"') + default: + p.parseError(fmt.Sprintf("invalid escape sequence '\\%c'", p.currentByte)) + return + } + escaped = false + } else { + switch p.currentByte { + case '"': + quoted = !quoted + if !quoted { + p.currentByte, p.err = p.buf.ReadByte() + return + } + case '\n': + p.parseError(fmt.Sprintf("label name %q contains unescaped new-line", p.currentToken.String())) + return + case '\\': + escaped = true + default: + p.currentToken.WriteByte(p.currentByte) + } + } p.currentByte, p.err = p.buf.ReadByte() - if p.err != nil || !isValidLabelNameContinuation(p.currentByte) { + if !isValidLabelNameContinuation(p.currentByte, quoted) || (!quoted && p.currentByte == '=') { return } } @@ -660,6 +779,7 @@ func (p *TextParser) readTokenAsLabelValue() { p.currentToken.WriteByte('\n') default: p.parseError(fmt.Sprintf("invalid escape sequence '\\%c'", p.currentByte)) + p.currentLabelPairs = nil return } escaped = false @@ -718,19 +838,19 @@ func (p *TextParser) setOrCreateCurrentMF() { } func isValidLabelNameStart(b byte) bool { - return (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || b == '_' + return (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || b == '_' || b == '"' } -func isValidLabelNameContinuation(b byte) bool { - return isValidLabelNameStart(b) || (b >= '0' && b <= '9') +func isValidLabelNameContinuation(b byte, quoted bool) bool { + return isValidLabelNameStart(b) || (b >= '0' && b <= '9') || (quoted && utf8.ValidString(string(b))) } func isValidMetricNameStart(b byte) bool { return isValidLabelNameStart(b) || b == ':' } -func isValidMetricNameContinuation(b byte) bool { - return isValidLabelNameContinuation(b) || b == ':' +func isValidMetricNameContinuation(b byte, quoted bool) bool { + return isValidLabelNameContinuation(b, quoted) || b == ':' } func isBlankOrTab(b byte) bool { @@ -775,7 +895,7 @@ func histogramMetricName(name string) string { func parseFloat(s string) (float64, error) { if strings.ContainsAny(s, "pP_") { - return 0, fmt.Errorf("unsupported character in float") + return 0, errors.New("unsupported character in float") } return strconv.ParseFloat(s, 64) } diff --git a/go-controller/vendor/github.com/prometheus/common/model/alert.go b/go-controller/vendor/github.com/prometheus/common/model/alert.go index 80d1fe944e..bd3a39e3e1 100644 --- a/go-controller/vendor/github.com/prometheus/common/model/alert.go +++ b/go-controller/vendor/github.com/prometheus/common/model/alert.go @@ -14,6 +14,7 @@ package model import ( + "errors" "fmt" "time" ) @@ -89,16 +90,16 @@ func (a *Alert) StatusAt(ts time.Time) AlertStatus { // Validate checks whether the alert data is inconsistent. func (a *Alert) Validate() error { if a.StartsAt.IsZero() { - return fmt.Errorf("start time missing") + return errors.New("start time missing") } if !a.EndsAt.IsZero() && a.EndsAt.Before(a.StartsAt) { - return fmt.Errorf("start time must be before end time") + return errors.New("start time must be before end time") } if err := a.Labels.Validate(); err != nil { return fmt.Errorf("invalid label set: %w", err) } if len(a.Labels) == 0 { - return fmt.Errorf("at least one label pair required") + return errors.New("at least one label pair required") } if err := a.Annotations.Validate(); err != nil { return fmt.Errorf("invalid annotations: %w", err) diff --git a/go-controller/vendor/github.com/prometheus/common/model/labels.go b/go-controller/vendor/github.com/prometheus/common/model/labels.go index 3317ce22ff..73b7aa3e60 100644 --- a/go-controller/vendor/github.com/prometheus/common/model/labels.go +++ b/go-controller/vendor/github.com/prometheus/common/model/labels.go @@ -97,26 +97,35 @@ var LabelNameRE = regexp.MustCompile("^[a-zA-Z_][a-zA-Z0-9_]*$") // therewith. type LabelName string -// IsValid returns true iff name matches the pattern of LabelNameRE for legacy -// names, and iff it's valid UTF-8 if NameValidationScheme is set to -// UTF8Validation. For the legacy matching, it does not use LabelNameRE for the -// check but a much faster hardcoded implementation. +// IsValid returns true iff the name matches the pattern of LabelNameRE when +// NameValidationScheme is set to LegacyValidation, or valid UTF-8 if +// NameValidationScheme is set to UTF8Validation. func (ln LabelName) IsValid() bool { if len(ln) == 0 { return false } switch NameValidationScheme { case LegacyValidation: - for i, b := range ln { - if !((b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || b == '_' || (b >= '0' && b <= '9' && i > 0)) { - return false - } - } + return ln.IsValidLegacy() case UTF8Validation: return utf8.ValidString(string(ln)) default: panic(fmt.Sprintf("Invalid name validation scheme requested: %d", NameValidationScheme)) } +} + +// IsValidLegacy returns true iff name matches the pattern of LabelNameRE for +// legacy names. It does not use LabelNameRE for the check but a much faster +// hardcoded implementation. +func (ln LabelName) IsValidLegacy() bool { + if len(ln) == 0 { + return false + } + for i, b := range ln { + if !((b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || b == '_' || (b >= '0' && b <= '9' && i > 0)) { + return false + } + } return true } diff --git a/go-controller/vendor/github.com/prometheus/common/model/labelset_string.go b/go-controller/vendor/github.com/prometheus/common/model/labelset_string.go index 481c47b46e..abb2c90018 100644 --- a/go-controller/vendor/github.com/prometheus/common/model/labelset_string.go +++ b/go-controller/vendor/github.com/prometheus/common/model/labelset_string.go @@ -11,8 +11,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:build go1.21 - package model import ( diff --git a/go-controller/vendor/github.com/prometheus/common/model/labelset_string_go120.go b/go-controller/vendor/github.com/prometheus/common/model/labelset_string_go120.go deleted file mode 100644 index c4212685e7..0000000000 --- a/go-controller/vendor/github.com/prometheus/common/model/labelset_string_go120.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2024 The Prometheus Authors -// 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. - -//go:build !go1.21 - -package model - -import ( - "fmt" - "sort" - "strings" -) - -// String was optimized using functions not available for go 1.20 -// or lower. We keep the old implementation for compatibility with client_golang. -// Once client golang drops support for go 1.20 (scheduled for August 2024), this -// file can be removed. -func (l LabelSet) String() string { - labelNames := make([]string, 0, len(l)) - for name := range l { - labelNames = append(labelNames, string(name)) - } - sort.Strings(labelNames) - lstrs := make([]string, 0, len(l)) - for _, name := range labelNames { - lstrs = append(lstrs, fmt.Sprintf("%s=%q", name, l[LabelName(name)])) - } - return fmt.Sprintf("{%s}", strings.Join(lstrs, ", ")) -} diff --git a/go-controller/vendor/github.com/prometheus/common/model/metric.go b/go-controller/vendor/github.com/prometheus/common/model/metric.go index eb865e5a59..5766107cf9 100644 --- a/go-controller/vendor/github.com/prometheus/common/model/metric.go +++ b/go-controller/vendor/github.com/prometheus/common/model/metric.go @@ -14,9 +14,11 @@ package model import ( + "errors" "fmt" "regexp" "sort" + "strconv" "strings" "unicode/utf8" @@ -26,18 +28,21 @@ import ( var ( // NameValidationScheme determines the method of name validation to be used by - // all calls to IsValidMetricName() and LabelName IsValid(). Setting UTF-8 mode - // in isolation from other components that don't support UTF-8 may result in - // bugs or other undefined behavior. This value is intended to be set by - // UTF-8-aware binaries as part of their startup. To avoid need for locking, - // this value should be set once, ideally in an init(), before multiple - // goroutines are started. - NameValidationScheme = LegacyValidation - - // NameEscapingScheme defines the default way that names will be - // escaped when presented to systems that do not support UTF-8 names. If the - // Content-Type "escaping" term is specified, that will override this value. - NameEscapingScheme = ValueEncodingEscaping + // all calls to IsValidMetricName() and LabelName IsValid(). Setting UTF-8 + // mode in isolation from other components that don't support UTF-8 may result + // in bugs or other undefined behavior. This value can be set to + // LegacyValidation during startup if a binary is not UTF-8-aware binaries. To + // avoid need for locking, this value should be set once, ideally in an + // init(), before multiple goroutines are started. + NameValidationScheme = UTF8Validation + + // NameEscapingScheme defines the default way that names will be escaped when + // presented to systems that do not support UTF-8 names. If the Content-Type + // "escaping" term is specified, that will override this value. + // NameEscapingScheme should not be set to the NoEscaping value. That string + // is used in content negotiation to indicate that a system supports UTF-8 and + // has that feature enabled. + NameEscapingScheme = UnderscoreEscaping ) // ValidationScheme is a Go enum for determining how metric and label names will @@ -161,7 +166,7 @@ func (m Metric) FastFingerprint() Fingerprint { func IsValidMetricName(n LabelValue) bool { switch NameValidationScheme { case LegacyValidation: - return IsValidLegacyMetricName(n) + return IsValidLegacyMetricName(string(n)) case UTF8Validation: if len(n) == 0 { return false @@ -176,7 +181,7 @@ func IsValidMetricName(n LabelValue) bool { // legacy validation scheme regardless of the value of NameValidationScheme. // This function, however, does not use MetricNameRE for the check but a much // faster hardcoded implementation. -func IsValidLegacyMetricName(n LabelValue) bool { +func IsValidLegacyMetricName(n string) bool { if len(n) == 0 { return false } @@ -208,7 +213,7 @@ func EscapeMetricFamily(v *dto.MetricFamily, scheme EscapingScheme) *dto.MetricF } // If the name is nil, copy as-is, don't try to escape. - if v.Name == nil || IsValidLegacyMetricName(LabelValue(v.GetName())) { + if v.Name == nil || IsValidLegacyMetricName(v.GetName()) { out.Name = v.Name } else { out.Name = proto.String(EscapeName(v.GetName(), scheme)) @@ -230,7 +235,7 @@ func EscapeMetricFamily(v *dto.MetricFamily, scheme EscapingScheme) *dto.MetricF for _, l := range m.Label { if l.GetName() == MetricNameLabel { - if l.Value == nil || IsValidLegacyMetricName(LabelValue(l.GetValue())) { + if l.Value == nil || IsValidLegacyMetricName(l.GetValue()) { escaped.Label = append(escaped.Label, l) continue } @@ -240,7 +245,7 @@ func EscapeMetricFamily(v *dto.MetricFamily, scheme EscapingScheme) *dto.MetricF }) continue } - if l.Name == nil || IsValidLegacyMetricName(LabelValue(l.GetName())) { + if l.Name == nil || IsValidLegacyMetricName(l.GetName()) { escaped.Label = append(escaped.Label, l) continue } @@ -256,20 +261,16 @@ func EscapeMetricFamily(v *dto.MetricFamily, scheme EscapingScheme) *dto.MetricF func metricNeedsEscaping(m *dto.Metric) bool { for _, l := range m.Label { - if l.GetName() == MetricNameLabel && !IsValidLegacyMetricName(LabelValue(l.GetValue())) { + if l.GetName() == MetricNameLabel && !IsValidLegacyMetricName(l.GetValue()) { return true } - if !IsValidLegacyMetricName(LabelValue(l.GetName())) { + if !IsValidLegacyMetricName(l.GetName()) { return true } } return false } -const ( - lowerhex = "0123456789abcdef" -) - // EscapeName escapes the incoming name according to the provided escaping // scheme. Depending on the rules of escaping, this may cause no change in the // string that is returned. (Especially NoEscaping, which by definition is a @@ -283,7 +284,7 @@ func EscapeName(name string, scheme EscapingScheme) string { case NoEscaping: return name case UnderscoreEscaping: - if IsValidLegacyMetricName(LabelValue(name)) { + if IsValidLegacyMetricName(name) { return name } for i, b := range name { @@ -304,31 +305,25 @@ func EscapeName(name string, scheme EscapingScheme) string { } else if isValidLegacyRune(b, i) { escaped.WriteRune(b) } else { - escaped.WriteRune('_') + escaped.WriteString("__") } } return escaped.String() case ValueEncodingEscaping: - if IsValidLegacyMetricName(LabelValue(name)) { + if IsValidLegacyMetricName(name) { return name } escaped.WriteString("U__") for i, b := range name { - if isValidLegacyRune(b, i) { + if b == '_' { + escaped.WriteString("__") + } else if isValidLegacyRune(b, i) { escaped.WriteRune(b) } else if !utf8.ValidRune(b) { escaped.WriteString("_FFFD_") - } else if b < 0x100 { - escaped.WriteRune('_') - for s := 4; s >= 0; s -= 4 { - escaped.WriteByte(lowerhex[b>>uint(s)&0xF]) - } - escaped.WriteRune('_') - } else if b < 0x10000 { + } else { escaped.WriteRune('_') - for s := 12; s >= 0; s -= 4 { - escaped.WriteByte(lowerhex[b>>uint(s)&0xF]) - } + escaped.WriteString(strconv.FormatInt(int64(b), 16)) escaped.WriteRune('_') } } @@ -386,8 +381,9 @@ func UnescapeName(name string, scheme EscapingScheme) string { // We think we are in a UTF-8 code, process it. var utf8Val uint for j := 0; i < len(escapedName); j++ { - // This is too many characters for a utf8 value. - if j > 4 { + // This is too many characters for a utf8 value based on the MaxRune + // value of '\U0010FFFF'. + if j >= 6 { return name } // Found a closing underscore, convert to a rune, check validity, and append. @@ -440,7 +436,7 @@ func (e EscapingScheme) String() string { func ToEscapingScheme(s string) (EscapingScheme, error) { if s == "" { - return NoEscaping, fmt.Errorf("got empty string instead of escaping scheme") + return NoEscaping, errors.New("got empty string instead of escaping scheme") } switch s { case AllowUTF8: @@ -452,6 +448,6 @@ func ToEscapingScheme(s string) (EscapingScheme, error) { case EscapeValues: return ValueEncodingEscaping, nil default: - return NoEscaping, fmt.Errorf("unknown format scheme " + s) + return NoEscaping, fmt.Errorf("unknown format scheme %s", s) } } diff --git a/go-controller/vendor/github.com/prometheus/common/model/silence.go b/go-controller/vendor/github.com/prometheus/common/model/silence.go index 910b0b71fc..8f91a9702e 100644 --- a/go-controller/vendor/github.com/prometheus/common/model/silence.go +++ b/go-controller/vendor/github.com/prometheus/common/model/silence.go @@ -15,6 +15,7 @@ package model import ( "encoding/json" + "errors" "fmt" "regexp" "time" @@ -34,7 +35,7 @@ func (m *Matcher) UnmarshalJSON(b []byte) error { } if len(m.Name) == 0 { - return fmt.Errorf("label name in matcher must not be empty") + return errors.New("label name in matcher must not be empty") } if m.IsRegex { if _, err := regexp.Compile(m.Value); err != nil { @@ -77,7 +78,7 @@ type Silence struct { // Validate returns true iff all fields of the silence have valid values. func (s *Silence) Validate() error { if len(s.Matchers) == 0 { - return fmt.Errorf("at least one matcher required") + return errors.New("at least one matcher required") } for _, m := range s.Matchers { if err := m.Validate(); err != nil { @@ -85,22 +86,22 @@ func (s *Silence) Validate() error { } } if s.StartsAt.IsZero() { - return fmt.Errorf("start time missing") + return errors.New("start time missing") } if s.EndsAt.IsZero() { - return fmt.Errorf("end time missing") + return errors.New("end time missing") } if s.EndsAt.Before(s.StartsAt) { - return fmt.Errorf("start time must be before end time") + return errors.New("start time must be before end time") } if s.CreatedBy == "" { - return fmt.Errorf("creator information missing") + return errors.New("creator information missing") } if s.Comment == "" { - return fmt.Errorf("comment missing") + return errors.New("comment missing") } if s.CreatedAt.IsZero() { - return fmt.Errorf("creation timestamp missing") + return errors.New("creation timestamp missing") } return nil } diff --git a/go-controller/vendor/github.com/prometheus/common/model/value_float.go b/go-controller/vendor/github.com/prometheus/common/model/value_float.go index ae35cc2ab4..6bfc757d18 100644 --- a/go-controller/vendor/github.com/prometheus/common/model/value_float.go +++ b/go-controller/vendor/github.com/prometheus/common/model/value_float.go @@ -15,6 +15,7 @@ package model import ( "encoding/json" + "errors" "fmt" "math" "strconv" @@ -39,7 +40,7 @@ func (v SampleValue) MarshalJSON() ([]byte, error) { // UnmarshalJSON implements json.Unmarshaler. func (v *SampleValue) UnmarshalJSON(b []byte) error { if len(b) < 2 || b[0] != '"' || b[len(b)-1] != '"' { - return fmt.Errorf("sample value must be a quoted string") + return errors.New("sample value must be a quoted string") } f, err := strconv.ParseFloat(string(b[1:len(b)-1]), 64) if err != nil { diff --git a/go-controller/vendor/github.com/prometheus/common/model/value_histogram.go b/go-controller/vendor/github.com/prometheus/common/model/value_histogram.go index 54bb038cff..895e6a3e83 100644 --- a/go-controller/vendor/github.com/prometheus/common/model/value_histogram.go +++ b/go-controller/vendor/github.com/prometheus/common/model/value_histogram.go @@ -15,6 +15,7 @@ package model import ( "encoding/json" + "errors" "fmt" "strconv" "strings" @@ -32,7 +33,7 @@ func (v FloatString) MarshalJSON() ([]byte, error) { func (v *FloatString) UnmarshalJSON(b []byte) error { if len(b) < 2 || b[0] != '"' || b[len(b)-1] != '"' { - return fmt.Errorf("float value must be a quoted string") + return errors.New("float value must be a quoted string") } f, err := strconv.ParseFloat(string(b[1:len(b)-1]), 64) if err != nil { @@ -141,7 +142,7 @@ type SampleHistogramPair struct { func (s SampleHistogramPair) MarshalJSON() ([]byte, error) { if s.Histogram == nil { - return nil, fmt.Errorf("histogram is nil") + return nil, errors.New("histogram is nil") } t, err := json.Marshal(s.Timestamp) if err != nil { @@ -164,7 +165,7 @@ func (s *SampleHistogramPair) UnmarshalJSON(buf []byte) error { return fmt.Errorf("wrong number of fields: %d != %d", gotLen, wantLen) } if s.Histogram == nil { - return fmt.Errorf("histogram is null") + return errors.New("histogram is null") } return nil } diff --git a/go-controller/vendor/github.com/stretchr/testify/assert/assertion_compare.go b/go-controller/vendor/github.com/stretchr/testify/assert/assertion_compare.go index 4d4b4aad6f..7e19eba090 100644 --- a/go-controller/vendor/github.com/stretchr/testify/assert/assertion_compare.go +++ b/go-controller/vendor/github.com/stretchr/testify/assert/assertion_compare.go @@ -7,10 +7,13 @@ import ( "time" ) -type CompareType int +// Deprecated: CompareType has only ever been for internal use and has accidentally been published since v1.6.0. Do not use it. +type CompareType = compareResult + +type compareResult int const ( - compareLess CompareType = iota - 1 + compareLess compareResult = iota - 1 compareEqual compareGreater ) @@ -39,7 +42,7 @@ var ( bytesType = reflect.TypeOf([]byte{}) ) -func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) { +func compare(obj1, obj2 interface{}, kind reflect.Kind) (compareResult, bool) { obj1Value := reflect.ValueOf(obj1) obj2Value := reflect.ValueOf(obj2) @@ -325,7 +328,13 @@ func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) { timeObj2 = obj2Value.Convert(timeType).Interface().(time.Time) } - return compare(timeObj1.UnixNano(), timeObj2.UnixNano(), reflect.Int64) + if timeObj1.Before(timeObj2) { + return compareLess, true + } + if timeObj1.Equal(timeObj2) { + return compareEqual, true + } + return compareGreater, true } case reflect.Slice: { @@ -345,7 +354,7 @@ func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) { bytesObj2 = obj2Value.Convert(bytesType).Interface().([]byte) } - return CompareType(bytes.Compare(bytesObj1, bytesObj2)), true + return compareResult(bytes.Compare(bytesObj1, bytesObj2)), true } case reflect.Uintptr: { @@ -381,7 +390,7 @@ func Greater(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface if h, ok := t.(tHelper); ok { h.Helper() } - return compareTwoValues(t, e1, e2, []CompareType{compareGreater}, "\"%v\" is not greater than \"%v\"", msgAndArgs...) + return compareTwoValues(t, e1, e2, []compareResult{compareGreater}, "\"%v\" is not greater than \"%v\"", msgAndArgs...) } // GreaterOrEqual asserts that the first element is greater than or equal to the second @@ -394,7 +403,7 @@ func GreaterOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...in if h, ok := t.(tHelper); ok { h.Helper() } - return compareTwoValues(t, e1, e2, []CompareType{compareGreater, compareEqual}, "\"%v\" is not greater than or equal to \"%v\"", msgAndArgs...) + return compareTwoValues(t, e1, e2, []compareResult{compareGreater, compareEqual}, "\"%v\" is not greater than or equal to \"%v\"", msgAndArgs...) } // Less asserts that the first element is less than the second @@ -406,7 +415,7 @@ func Less(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) if h, ok := t.(tHelper); ok { h.Helper() } - return compareTwoValues(t, e1, e2, []CompareType{compareLess}, "\"%v\" is not less than \"%v\"", msgAndArgs...) + return compareTwoValues(t, e1, e2, []compareResult{compareLess}, "\"%v\" is not less than \"%v\"", msgAndArgs...) } // LessOrEqual asserts that the first element is less than or equal to the second @@ -419,7 +428,7 @@ func LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...inter if h, ok := t.(tHelper); ok { h.Helper() } - return compareTwoValues(t, e1, e2, []CompareType{compareLess, compareEqual}, "\"%v\" is not less than or equal to \"%v\"", msgAndArgs...) + return compareTwoValues(t, e1, e2, []compareResult{compareLess, compareEqual}, "\"%v\" is not less than or equal to \"%v\"", msgAndArgs...) } // Positive asserts that the specified element is positive @@ -431,7 +440,7 @@ func Positive(t TestingT, e interface{}, msgAndArgs ...interface{}) bool { h.Helper() } zero := reflect.Zero(reflect.TypeOf(e)) - return compareTwoValues(t, e, zero.Interface(), []CompareType{compareGreater}, "\"%v\" is not positive", msgAndArgs...) + return compareTwoValues(t, e, zero.Interface(), []compareResult{compareGreater}, "\"%v\" is not positive", msgAndArgs...) } // Negative asserts that the specified element is negative @@ -443,10 +452,10 @@ func Negative(t TestingT, e interface{}, msgAndArgs ...interface{}) bool { h.Helper() } zero := reflect.Zero(reflect.TypeOf(e)) - return compareTwoValues(t, e, zero.Interface(), []CompareType{compareLess}, "\"%v\" is not negative", msgAndArgs...) + return compareTwoValues(t, e, zero.Interface(), []compareResult{compareLess}, "\"%v\" is not negative", msgAndArgs...) } -func compareTwoValues(t TestingT, e1 interface{}, e2 interface{}, allowedComparesResults []CompareType, failMessage string, msgAndArgs ...interface{}) bool { +func compareTwoValues(t TestingT, e1 interface{}, e2 interface{}, allowedComparesResults []compareResult, failMessage string, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() } @@ -469,7 +478,7 @@ func compareTwoValues(t TestingT, e1 interface{}, e2 interface{}, allowedCompare return true } -func containsValue(values []CompareType, value CompareType) bool { +func containsValue(values []compareResult, value compareResult) bool { for _, v := range values { if v == value { return true diff --git a/go-controller/vendor/github.com/stretchr/testify/assert/assertion_format.go b/go-controller/vendor/github.com/stretchr/testify/assert/assertion_format.go index 3ddab109ad..1906341657 100644 --- a/go-controller/vendor/github.com/stretchr/testify/assert/assertion_format.go +++ b/go-controller/vendor/github.com/stretchr/testify/assert/assertion_format.go @@ -104,8 +104,8 @@ func EqualExportedValuesf(t TestingT, expected interface{}, actual interface{}, return EqualExportedValues(t, expected, actual, append([]interface{}{msg}, args...)...) } -// EqualValuesf asserts that two objects are equal or convertible to the same types -// and equal. +// EqualValuesf asserts that two objects are equal or convertible to the larger +// type and equal. // // assert.EqualValuesf(t, uint32(123), int32(123), "error message %s", "formatted") func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool { @@ -186,7 +186,7 @@ func Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick // assert.EventuallyWithTf(t, func(c *assert.CollectT, "error message %s", "formatted") { // // add assertions as needed; any assertion failure will fail the current tick // assert.True(c, externalValue, "expected 'externalValue' to be true") -// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") +// }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") func EventuallyWithTf(t TestingT, condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -568,6 +568,23 @@ func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, a return NotContains(t, s, contains, append([]interface{}{msg}, args...)...) } +// NotElementsMatchf asserts that the specified listA(array, slice...) is NOT equal to specified +// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, +// the number of appearances of each of them in both lists should not match. +// This is an inverse of ElementsMatch. +// +// assert.NotElementsMatchf(t, [1, 1, 2, 3], [1, 1, 2, 3], "error message %s", "formatted") -> false +// +// assert.NotElementsMatchf(t, [1, 1, 2, 3], [1, 2, 3], "error message %s", "formatted") -> true +// +// assert.NotElementsMatchf(t, [1, 2, 3], [1, 2, 4], "error message %s", "formatted") -> true +func NotElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return NotElementsMatch(t, listA, listB, append([]interface{}{msg}, args...)...) +} + // NotEmptyf asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either // a slice or a channel with len == 0. // @@ -604,7 +621,16 @@ func NotEqualValuesf(t TestingT, expected interface{}, actual interface{}, msg s return NotEqualValues(t, expected, actual, append([]interface{}{msg}, args...)...) } -// NotErrorIsf asserts that at none of the errors in err's chain matches target. +// NotErrorAsf asserts that none of the errors in err's chain matches target, +// but if so, sets target to that error value. +func NotErrorAsf(t TestingT, err error, target interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return NotErrorAs(t, err, target, append([]interface{}{msg}, args...)...) +} + +// NotErrorIsf asserts that none of the errors in err's chain matches target. // This is a wrapper for errors.Is. func NotErrorIsf(t TestingT, err error, target error, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { diff --git a/go-controller/vendor/github.com/stretchr/testify/assert/assertion_forward.go b/go-controller/vendor/github.com/stretchr/testify/assert/assertion_forward.go index a84e09bd40..21629087ba 100644 --- a/go-controller/vendor/github.com/stretchr/testify/assert/assertion_forward.go +++ b/go-controller/vendor/github.com/stretchr/testify/assert/assertion_forward.go @@ -186,8 +186,8 @@ func (a *Assertions) EqualExportedValuesf(expected interface{}, actual interface return EqualExportedValuesf(a.t, expected, actual, msg, args...) } -// EqualValues asserts that two objects are equal or convertible to the same types -// and equal. +// EqualValues asserts that two objects are equal or convertible to the larger +// type and equal. // // a.EqualValues(uint32(123), int32(123)) func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { @@ -197,8 +197,8 @@ func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAn return EqualValues(a.t, expected, actual, msgAndArgs...) } -// EqualValuesf asserts that two objects are equal or convertible to the same types -// and equal. +// EqualValuesf asserts that two objects are equal or convertible to the larger +// type and equal. // // a.EqualValuesf(uint32(123), int32(123), "error message %s", "formatted") func (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool { @@ -336,7 +336,7 @@ func (a *Assertions) Eventually(condition func() bool, waitFor time.Duration, ti // a.EventuallyWithT(func(c *assert.CollectT) { // // add assertions as needed; any assertion failure will fail the current tick // assert.True(c, externalValue, "expected 'externalValue' to be true") -// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") +// }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") func (a *Assertions) EventuallyWithT(condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -361,7 +361,7 @@ func (a *Assertions) EventuallyWithT(condition func(collect *CollectT), waitFor // a.EventuallyWithTf(func(c *assert.CollectT, "error message %s", "formatted") { // // add assertions as needed; any assertion failure will fail the current tick // assert.True(c, externalValue, "expected 'externalValue' to be true") -// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") +// }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") func (a *Assertions) EventuallyWithTf(condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1128,6 +1128,40 @@ func (a *Assertions) NotContainsf(s interface{}, contains interface{}, msg strin return NotContainsf(a.t, s, contains, msg, args...) } +// NotElementsMatch asserts that the specified listA(array, slice...) is NOT equal to specified +// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, +// the number of appearances of each of them in both lists should not match. +// This is an inverse of ElementsMatch. +// +// a.NotElementsMatch([1, 1, 2, 3], [1, 1, 2, 3]) -> false +// +// a.NotElementsMatch([1, 1, 2, 3], [1, 2, 3]) -> true +// +// a.NotElementsMatch([1, 2, 3], [1, 2, 4]) -> true +func (a *Assertions) NotElementsMatch(listA interface{}, listB interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotElementsMatch(a.t, listA, listB, msgAndArgs...) +} + +// NotElementsMatchf asserts that the specified listA(array, slice...) is NOT equal to specified +// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, +// the number of appearances of each of them in both lists should not match. +// This is an inverse of ElementsMatch. +// +// a.NotElementsMatchf([1, 1, 2, 3], [1, 1, 2, 3], "error message %s", "formatted") -> false +// +// a.NotElementsMatchf([1, 1, 2, 3], [1, 2, 3], "error message %s", "formatted") -> true +// +// a.NotElementsMatchf([1, 2, 3], [1, 2, 4], "error message %s", "formatted") -> true +func (a *Assertions) NotElementsMatchf(listA interface{}, listB interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotElementsMatchf(a.t, listA, listB, msg, args...) +} + // NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either // a slice or a channel with len == 0. // @@ -1200,7 +1234,25 @@ func (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg str return NotEqualf(a.t, expected, actual, msg, args...) } -// NotErrorIs asserts that at none of the errors in err's chain matches target. +// NotErrorAs asserts that none of the errors in err's chain matches target, +// but if so, sets target to that error value. +func (a *Assertions) NotErrorAs(err error, target interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotErrorAs(a.t, err, target, msgAndArgs...) +} + +// NotErrorAsf asserts that none of the errors in err's chain matches target, +// but if so, sets target to that error value. +func (a *Assertions) NotErrorAsf(err error, target interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotErrorAsf(a.t, err, target, msg, args...) +} + +// NotErrorIs asserts that none of the errors in err's chain matches target. // This is a wrapper for errors.Is. func (a *Assertions) NotErrorIs(err error, target error, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { @@ -1209,7 +1261,7 @@ func (a *Assertions) NotErrorIs(err error, target error, msgAndArgs ...interface return NotErrorIs(a.t, err, target, msgAndArgs...) } -// NotErrorIsf asserts that at none of the errors in err's chain matches target. +// NotErrorIsf asserts that none of the errors in err's chain matches target. // This is a wrapper for errors.Is. func (a *Assertions) NotErrorIsf(err error, target error, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { diff --git a/go-controller/vendor/github.com/stretchr/testify/assert/assertion_order.go b/go-controller/vendor/github.com/stretchr/testify/assert/assertion_order.go index 00df62a059..1d2f71824a 100644 --- a/go-controller/vendor/github.com/stretchr/testify/assert/assertion_order.go +++ b/go-controller/vendor/github.com/stretchr/testify/assert/assertion_order.go @@ -6,7 +6,7 @@ import ( ) // isOrdered checks that collection contains orderable elements. -func isOrdered(t TestingT, object interface{}, allowedComparesResults []CompareType, failMessage string, msgAndArgs ...interface{}) bool { +func isOrdered(t TestingT, object interface{}, allowedComparesResults []compareResult, failMessage string, msgAndArgs ...interface{}) bool { objKind := reflect.TypeOf(object).Kind() if objKind != reflect.Slice && objKind != reflect.Array { return false @@ -50,7 +50,7 @@ func isOrdered(t TestingT, object interface{}, allowedComparesResults []CompareT // assert.IsIncreasing(t, []float{1, 2}) // assert.IsIncreasing(t, []string{"a", "b"}) func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { - return isOrdered(t, object, []CompareType{compareLess}, "\"%v\" is not less than \"%v\"", msgAndArgs...) + return isOrdered(t, object, []compareResult{compareLess}, "\"%v\" is not less than \"%v\"", msgAndArgs...) } // IsNonIncreasing asserts that the collection is not increasing @@ -59,7 +59,7 @@ func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) boo // assert.IsNonIncreasing(t, []float{2, 1}) // assert.IsNonIncreasing(t, []string{"b", "a"}) func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { - return isOrdered(t, object, []CompareType{compareEqual, compareGreater}, "\"%v\" is not greater than or equal to \"%v\"", msgAndArgs...) + return isOrdered(t, object, []compareResult{compareEqual, compareGreater}, "\"%v\" is not greater than or equal to \"%v\"", msgAndArgs...) } // IsDecreasing asserts that the collection is decreasing @@ -68,7 +68,7 @@ func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) // assert.IsDecreasing(t, []float{2, 1}) // assert.IsDecreasing(t, []string{"b", "a"}) func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { - return isOrdered(t, object, []CompareType{compareGreater}, "\"%v\" is not greater than \"%v\"", msgAndArgs...) + return isOrdered(t, object, []compareResult{compareGreater}, "\"%v\" is not greater than \"%v\"", msgAndArgs...) } // IsNonDecreasing asserts that the collection is not decreasing @@ -77,5 +77,5 @@ func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) boo // assert.IsNonDecreasing(t, []float{1, 2}) // assert.IsNonDecreasing(t, []string{"a", "b"}) func IsNonDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { - return isOrdered(t, object, []CompareType{compareLess, compareEqual}, "\"%v\" is not less than or equal to \"%v\"", msgAndArgs...) + return isOrdered(t, object, []compareResult{compareLess, compareEqual}, "\"%v\" is not less than or equal to \"%v\"", msgAndArgs...) } diff --git a/go-controller/vendor/github.com/stretchr/testify/assert/assertions.go b/go-controller/vendor/github.com/stretchr/testify/assert/assertions.go index 0b7570f21c..4e91332bb5 100644 --- a/go-controller/vendor/github.com/stretchr/testify/assert/assertions.go +++ b/go-controller/vendor/github.com/stretchr/testify/assert/assertions.go @@ -19,7 +19,9 @@ import ( "github.com/davecgh/go-spew/spew" "github.com/pmezard/go-difflib/difflib" - "gopkg.in/yaml.v3" + + // Wrapper around gopkg.in/yaml.v3 + "github.com/stretchr/testify/assert/yaml" ) //go:generate sh -c "cd ../_codegen && go build && cd - && ../_codegen/_codegen -output-package=assert -template=assertion_format.go.tmpl" @@ -45,6 +47,10 @@ type BoolAssertionFunc func(TestingT, bool, ...interface{}) bool // for table driven tests. type ErrorAssertionFunc func(TestingT, error, ...interface{}) bool +// PanicAssertionFunc is a common function prototype when validating a panic value. Can be useful +// for table driven tests. +type PanicAssertionFunc = func(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool + // Comparison is a custom function that returns true on success and false on failure type Comparison func() (success bool) @@ -496,7 +502,13 @@ func Same(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) b h.Helper() } - if !samePointers(expected, actual) { + same, ok := samePointers(expected, actual) + if !ok { + return Fail(t, "Both arguments must be pointers", msgAndArgs...) + } + + if !same { + // both are pointers but not the same type & pointing to the same address return Fail(t, fmt.Sprintf("Not same: \n"+ "expected: %p %#v\n"+ "actual : %p %#v", expected, expected, actual, actual), msgAndArgs...) @@ -516,7 +528,13 @@ func NotSame(t TestingT, expected, actual interface{}, msgAndArgs ...interface{} h.Helper() } - if samePointers(expected, actual) { + same, ok := samePointers(expected, actual) + if !ok { + //fails when the arguments are not pointers + return !(Fail(t, "Both arguments must be pointers", msgAndArgs...)) + } + + if same { return Fail(t, fmt.Sprintf( "Expected and actual point to the same object: %p %#v", expected, expected), msgAndArgs...) @@ -524,21 +542,23 @@ func NotSame(t TestingT, expected, actual interface{}, msgAndArgs ...interface{} return true } -// samePointers compares two generic interface objects and returns whether -// they point to the same object -func samePointers(first, second interface{}) bool { +// samePointers checks if two generic interface objects are pointers of the same +// type pointing to the same object. It returns two values: same indicating if +// they are the same type and point to the same object, and ok indicating that +// both inputs are pointers. +func samePointers(first, second interface{}) (same bool, ok bool) { firstPtr, secondPtr := reflect.ValueOf(first), reflect.ValueOf(second) if firstPtr.Kind() != reflect.Ptr || secondPtr.Kind() != reflect.Ptr { - return false + return false, false //not both are pointers } firstType, secondType := reflect.TypeOf(first), reflect.TypeOf(second) if firstType != secondType { - return false + return false, true // both are pointers, but of different types } // compare pointer addresses - return first == second + return first == second, true } // formatUnequalValues takes two values of arbitrary types and returns string @@ -572,8 +592,8 @@ func truncatingFormat(data interface{}) string { return value } -// EqualValues asserts that two objects are equal or convertible to the same types -// and equal. +// EqualValues asserts that two objects are equal or convertible to the larger +// type and equal. // // assert.EqualValues(t, uint32(123), int32(123)) func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { @@ -615,21 +635,6 @@ func EqualExportedValues(t TestingT, expected, actual interface{}, msgAndArgs .. return Fail(t, fmt.Sprintf("Types expected to match exactly\n\t%v != %v", aType, bType), msgAndArgs...) } - if aType.Kind() == reflect.Ptr { - aType = aType.Elem() - } - if bType.Kind() == reflect.Ptr { - bType = bType.Elem() - } - - if aType.Kind() != reflect.Struct { - return Fail(t, fmt.Sprintf("Types expected to both be struct or pointer to struct \n\t%v != %v", aType.Kind(), reflect.Struct), msgAndArgs...) - } - - if bType.Kind() != reflect.Struct { - return Fail(t, fmt.Sprintf("Types expected to both be struct or pointer to struct \n\t%v != %v", bType.Kind(), reflect.Struct), msgAndArgs...) - } - expected = copyExportedFields(expected) actual = copyExportedFields(actual) @@ -1170,6 +1175,39 @@ func formatListDiff(listA, listB interface{}, extraA, extraB []interface{}) stri return msg.String() } +// NotElementsMatch asserts that the specified listA(array, slice...) is NOT equal to specified +// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, +// the number of appearances of each of them in both lists should not match. +// This is an inverse of ElementsMatch. +// +// assert.NotElementsMatch(t, [1, 1, 2, 3], [1, 1, 2, 3]) -> false +// +// assert.NotElementsMatch(t, [1, 1, 2, 3], [1, 2, 3]) -> true +// +// assert.NotElementsMatch(t, [1, 2, 3], [1, 2, 4]) -> true +func NotElementsMatch(t TestingT, listA, listB interface{}, msgAndArgs ...interface{}) (ok bool) { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if isEmpty(listA) && isEmpty(listB) { + return Fail(t, "listA and listB contain the same elements", msgAndArgs) + } + + if !isList(t, listA, msgAndArgs...) { + return Fail(t, "listA is not a list type", msgAndArgs...) + } + if !isList(t, listB, msgAndArgs...) { + return Fail(t, "listB is not a list type", msgAndArgs...) + } + + extraA, extraB := diffLists(listA, listB) + if len(extraA) == 0 && len(extraB) == 0 { + return Fail(t, "listA and listB contain the same elements", msgAndArgs) + } + + return true +} + // Condition uses a Comparison to assert a complex condition. func Condition(t TestingT, comp Comparison, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { @@ -1488,6 +1526,9 @@ func InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAnd if err != nil { return Fail(t, err.Error(), msgAndArgs...) } + if math.IsNaN(actualEpsilon) { + return Fail(t, "relative error is NaN", msgAndArgs...) + } if actualEpsilon > epsilon { return Fail(t, fmt.Sprintf("Relative error is too high: %#v (expected)\n"+ " < %#v (actual)", epsilon, actualEpsilon), msgAndArgs...) @@ -1611,7 +1652,6 @@ func ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...in // matchRegexp return true if a specified regexp matches a string. func matchRegexp(rx interface{}, str interface{}) bool { - var r *regexp.Regexp if rr, ok := rx.(*regexp.Regexp); ok { r = rr @@ -1619,7 +1659,14 @@ func matchRegexp(rx interface{}, str interface{}) bool { r = regexp.MustCompile(fmt.Sprint(rx)) } - return (r.FindStringIndex(fmt.Sprint(str)) != nil) + switch v := str.(type) { + case []byte: + return r.Match(v) + case string: + return r.MatchString(v) + default: + return r.MatchString(fmt.Sprint(v)) + } } @@ -1872,7 +1919,7 @@ var spewConfigStringerEnabled = spew.ConfigState{ MaxDepth: 10, } -type tHelper interface { +type tHelper = interface { Helper() } @@ -1911,6 +1958,9 @@ func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick t // CollectT implements the TestingT interface and collects all errors. type CollectT struct { + // A slice of errors. Non-nil slice denotes a failure. + // If it's non-nil but len(c.errors) == 0, this is also a failure + // obtained by direct c.FailNow() call. errors []error } @@ -1919,9 +1969,10 @@ func (c *CollectT) Errorf(format string, args ...interface{}) { c.errors = append(c.errors, fmt.Errorf(format, args...)) } -// FailNow panics. -func (*CollectT) FailNow() { - panic("Assertion failed") +// FailNow stops execution by calling runtime.Goexit. +func (c *CollectT) FailNow() { + c.fail() + runtime.Goexit() } // Deprecated: That was a method for internal usage that should not have been published. Now just panics. @@ -1934,6 +1985,16 @@ func (*CollectT) Copy(TestingT) { panic("Copy() is deprecated") } +func (c *CollectT) fail() { + if !c.failed() { + c.errors = []error{} // Make it non-nil to mark a failure. + } +} + +func (c *CollectT) failed() bool { + return c.errors != nil +} + // EventuallyWithT asserts that given condition will be met in waitFor time, // periodically checking target function each tick. In contrast to Eventually, // it supplies a CollectT to the condition function, so that the condition @@ -1951,14 +2012,14 @@ func (*CollectT) Copy(TestingT) { // assert.EventuallyWithT(t, func(c *assert.CollectT) { // // add assertions as needed; any assertion failure will fail the current tick // assert.True(c, externalValue, "expected 'externalValue' to be true") -// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") +// }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") func EventuallyWithT(t TestingT, condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() } var lastFinishedTickErrs []error - ch := make(chan []error, 1) + ch := make(chan *CollectT, 1) timer := time.NewTimer(waitFor) defer timer.Stop() @@ -1978,16 +2039,16 @@ func EventuallyWithT(t TestingT, condition func(collect *CollectT), waitFor time go func() { collect := new(CollectT) defer func() { - ch <- collect.errors + ch <- collect }() condition(collect) }() - case errs := <-ch: - if len(errs) == 0 { + case collect := <-ch: + if !collect.failed() { return true } // Keep the errors from the last ended condition, so that they can be copied to t if timeout is reached. - lastFinishedTickErrs = errs + lastFinishedTickErrs = collect.errors tick = ticker.C } } @@ -2049,7 +2110,7 @@ func ErrorIs(t TestingT, err, target error, msgAndArgs ...interface{}) bool { ), msgAndArgs...) } -// NotErrorIs asserts that at none of the errors in err's chain matches target. +// NotErrorIs asserts that none of the errors in err's chain matches target. // This is a wrapper for errors.Is. func NotErrorIs(t TestingT, err, target error, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { @@ -2090,6 +2151,24 @@ func ErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{ ), msgAndArgs...) } +// NotErrorAs asserts that none of the errors in err's chain matches target, +// but if so, sets target to that error value. +func NotErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if !errors.As(err, target) { + return true + } + + chain := buildErrorChainString(err) + + return Fail(t, fmt.Sprintf("Target error should not be in err chain:\n"+ + "found: %q\n"+ + "in chain: %s", target, chain, + ), msgAndArgs...) +} + func buildErrorChainString(err error) string { if err == nil { return "" diff --git a/go-controller/vendor/github.com/stretchr/testify/assert/yaml/yaml_custom.go b/go-controller/vendor/github.com/stretchr/testify/assert/yaml/yaml_custom.go new file mode 100644 index 0000000000..baa0cc7d7f --- /dev/null +++ b/go-controller/vendor/github.com/stretchr/testify/assert/yaml/yaml_custom.go @@ -0,0 +1,25 @@ +//go:build testify_yaml_custom && !testify_yaml_fail && !testify_yaml_default +// +build testify_yaml_custom,!testify_yaml_fail,!testify_yaml_default + +// Package yaml is an implementation of YAML functions that calls a pluggable implementation. +// +// This implementation is selected with the testify_yaml_custom build tag. +// +// go test -tags testify_yaml_custom +// +// This implementation can be used at build time to replace the default implementation +// to avoid linking with [gopkg.in/yaml.v3]. +// +// In your test package: +// +// import assertYaml "github.com/stretchr/testify/assert/yaml" +// +// func init() { +// assertYaml.Unmarshal = func (in []byte, out interface{}) error { +// // ... +// return nil +// } +// } +package yaml + +var Unmarshal func(in []byte, out interface{}) error diff --git a/go-controller/vendor/github.com/stretchr/testify/assert/yaml/yaml_default.go b/go-controller/vendor/github.com/stretchr/testify/assert/yaml/yaml_default.go new file mode 100644 index 0000000000..b83c6cf64c --- /dev/null +++ b/go-controller/vendor/github.com/stretchr/testify/assert/yaml/yaml_default.go @@ -0,0 +1,37 @@ +//go:build !testify_yaml_fail && !testify_yaml_custom +// +build !testify_yaml_fail,!testify_yaml_custom + +// Package yaml is just an indirection to handle YAML deserialization. +// +// This package is just an indirection that allows the builder to override the +// indirection with an alternative implementation of this package that uses +// another implementation of YAML deserialization. This allows to not either not +// use YAML deserialization at all, or to use another implementation than +// [gopkg.in/yaml.v3] (for example for license compatibility reasons, see [PR #1120]). +// +// Alternative implementations are selected using build tags: +// +// - testify_yaml_fail: [Unmarshal] always fails with an error +// - testify_yaml_custom: [Unmarshal] is a variable. Caller must initialize it +// before calling any of [github.com/stretchr/testify/assert.YAMLEq] or +// [github.com/stretchr/testify/assert.YAMLEqf]. +// +// Usage: +// +// go test -tags testify_yaml_fail +// +// You can check with "go list" which implementation is linked: +// +// go list -f '{{.Imports}}' github.com/stretchr/testify/assert/yaml +// go list -tags testify_yaml_fail -f '{{.Imports}}' github.com/stretchr/testify/assert/yaml +// go list -tags testify_yaml_custom -f '{{.Imports}}' github.com/stretchr/testify/assert/yaml +// +// [PR #1120]: https://github.com/stretchr/testify/pull/1120 +package yaml + +import goyaml "gopkg.in/yaml.v3" + +// Unmarshal is just a wrapper of [gopkg.in/yaml.v3.Unmarshal]. +func Unmarshal(in []byte, out interface{}) error { + return goyaml.Unmarshal(in, out) +} diff --git a/go-controller/vendor/github.com/stretchr/testify/assert/yaml/yaml_fail.go b/go-controller/vendor/github.com/stretchr/testify/assert/yaml/yaml_fail.go new file mode 100644 index 0000000000..e78f7dfe69 --- /dev/null +++ b/go-controller/vendor/github.com/stretchr/testify/assert/yaml/yaml_fail.go @@ -0,0 +1,18 @@ +//go:build testify_yaml_fail && !testify_yaml_custom && !testify_yaml_default +// +build testify_yaml_fail,!testify_yaml_custom,!testify_yaml_default + +// Package yaml is an implementation of YAML functions that always fail. +// +// This implementation can be used at build time to replace the default implementation +// to avoid linking with [gopkg.in/yaml.v3]: +// +// go test -tags testify_yaml_fail +package yaml + +import "errors" + +var errNotImplemented = errors.New("YAML functions are not available (see https://pkg.go.dev/github.com/stretchr/testify/assert/yaml)") + +func Unmarshal([]byte, interface{}) error { + return errNotImplemented +} diff --git a/go-controller/vendor/github.com/stretchr/testify/mock/mock.go b/go-controller/vendor/github.com/stretchr/testify/mock/mock.go index 213bde2ea6..eb5682df97 100644 --- a/go-controller/vendor/github.com/stretchr/testify/mock/mock.go +++ b/go-controller/vendor/github.com/stretchr/testify/mock/mock.go @@ -80,12 +80,12 @@ type Call struct { requires []*Call } -func newCall(parent *Mock, methodName string, callerInfo []string, methodArguments ...interface{}) *Call { +func newCall(parent *Mock, methodName string, callerInfo []string, methodArguments Arguments, returnArguments Arguments) *Call { return &Call{ Parent: parent, Method: methodName, Arguments: methodArguments, - ReturnArguments: make([]interface{}, 0), + ReturnArguments: returnArguments, callerInfo: callerInfo, Repeatability: 0, WaitFor: nil, @@ -256,7 +256,7 @@ func (c *Call) Unset() *Call { // calls have been called as expected. The referenced calls may be from the // same mock instance and/or other mock instances. // -// Mock.On("Do").Return(nil).Notbefore( +// Mock.On("Do").Return(nil).NotBefore( // Mock.On("Init").Return(nil) // ) func (c *Call) NotBefore(calls ...*Call) *Call { @@ -273,6 +273,20 @@ func (c *Call) NotBefore(calls ...*Call) *Call { return c } +// InOrder defines the order in which the calls should be made +// +// For example: +// +// InOrder( +// Mock.On("init").Return(nil), +// Mock.On("Do").Return(nil), +// ) +func InOrder(calls ...*Call) { + for i := 1; i < len(calls); i++ { + calls[i].NotBefore(calls[i-1]) + } +} + // Mock is the workhorse used to track activity on another object. // For an example of its usage, refer to the "Example Usage" section at the top // of this document. @@ -351,7 +365,8 @@ func (m *Mock) On(methodName string, arguments ...interface{}) *Call { m.mutex.Lock() defer m.mutex.Unlock() - c := newCall(m, methodName, assert.CallerInfo(), arguments...) + + c := newCall(m, methodName, assert.CallerInfo(), arguments, make([]interface{}, 0)) m.ExpectedCalls = append(m.ExpectedCalls, c) return c } @@ -491,11 +506,12 @@ func (m *Mock) MethodCalled(methodName string, arguments ...interface{}) Argumen m.mutex.Unlock() if closestCall != nil { - m.fail("\n\nmock: Unexpected Method Call\n-----------------------------\n\n%s\n\nThe closest call I have is: \n\n%s\n\n%s\nDiff: %s", + m.fail("\n\nmock: Unexpected Method Call\n-----------------------------\n\n%s\n\nThe closest call I have is: \n\n%s\n\n%s\nDiff: %s\nat: %s\n", callString(methodName, arguments, true), callString(methodName, closestCall.Arguments, true), diffArguments(closestCall.Arguments, arguments), strings.TrimSpace(mismatch), + assert.CallerInfo(), ) } else { m.fail("\nassert: mock: I don't know what to return because the method call was unexpected.\n\tEither do Mock.On(\"%s\").Return(...) first, or remove the %s() call.\n\tThis method was unexpected:\n\t\t%s\n\tat: %s", methodName, methodName, callString(methodName, arguments, true), assert.CallerInfo()) @@ -529,7 +545,7 @@ func (m *Mock) MethodCalled(methodName string, arguments ...interface{}) Argumen call.totalCalls++ // add the call - m.Calls = append(m.Calls, *newCall(m, methodName, assert.CallerInfo(), arguments...)) + m.Calls = append(m.Calls, *newCall(m, methodName, assert.CallerInfo(), arguments, call.ReturnArguments)) m.mutex.Unlock() // block if specified @@ -764,9 +780,17 @@ const ( ) // AnythingOfTypeArgument contains the type of an argument -// for use when type checking. Used in Diff and Assert. +// for use when type checking. Used in [Arguments.Diff] and [Arguments.Assert]. // -// Deprecated: this is an implementation detail that must not be used. Use [AnythingOfType] instead. +// Deprecated: this is an implementation detail that must not be used. Use the [AnythingOfType] constructor instead, example: +// +// m.On("Do", mock.AnythingOfType("string")) +// +// All explicit type declarations can be replaced with interface{} as is expected by [Mock.On], example: +// +// func anyString interface{} { +// return mock.AnythingOfType("string") +// } type AnythingOfTypeArgument = anythingOfTypeArgument // anythingOfTypeArgument is a string that contains the type of an argument @@ -780,53 +804,54 @@ type anythingOfTypeArgument string // // For example: // -// Assert(t, AnythingOfType("string"), AnythingOfType("int")) +// args.Assert(t, AnythingOfType("string"), AnythingOfType("int")) func AnythingOfType(t string) AnythingOfTypeArgument { return anythingOfTypeArgument(t) } // IsTypeArgument is a struct that contains the type of an argument -// for use when type checking. This is an alternative to AnythingOfType. -// Used in Diff and Assert. +// for use when type checking. This is an alternative to [AnythingOfType]. +// Used in [Arguments.Diff] and [Arguments.Assert]. type IsTypeArgument struct { t reflect.Type } // IsType returns an IsTypeArgument object containing the type to check for. // You can provide a zero-value of the type to check. This is an -// alternative to AnythingOfType. Used in Diff and Assert. +// alternative to [AnythingOfType]. Used in [Arguments.Diff] and [Arguments.Assert]. // // For example: -// Assert(t, IsType(""), IsType(0)) +// +// args.Assert(t, IsType(""), IsType(0)) func IsType(t interface{}) *IsTypeArgument { return &IsTypeArgument{t: reflect.TypeOf(t)} } -// FunctionalOptionsArgument is a struct that contains the type and value of an functional option argument -// for use when type checking. +// FunctionalOptionsArgument contains a list of functional options arguments +// expected for use when matching a list of arguments. type FunctionalOptionsArgument struct { - value interface{} + values []interface{} } // String returns the string representation of FunctionalOptionsArgument func (f *FunctionalOptionsArgument) String() string { var name string - tValue := reflect.ValueOf(f.value) - if tValue.Len() > 0 { - name = "[]" + reflect.TypeOf(tValue.Index(0).Interface()).String() + if len(f.values) > 0 { + name = "[]" + reflect.TypeOf(f.values[0]).String() } - return strings.Replace(fmt.Sprintf("%#v", f.value), "[]interface {}", name, 1) + return strings.Replace(fmt.Sprintf("%#v", f.values), "[]interface {}", name, 1) } -// FunctionalOptions returns an FunctionalOptionsArgument object containing the functional option type -// and the values to check of +// FunctionalOptions returns an [FunctionalOptionsArgument] object containing +// the expected functional-options to check for. // // For example: -// Assert(t, FunctionalOptions("[]foo.FunctionalOption", foo.Opt1(), foo.Opt2())) -func FunctionalOptions(value ...interface{}) *FunctionalOptionsArgument { +// +// args.Assert(t, FunctionalOptions(foo.Opt1("strValue"), foo.Opt2(613))) +func FunctionalOptions(values ...interface{}) *FunctionalOptionsArgument { return &FunctionalOptionsArgument{ - value: value, + values: values, } } @@ -873,10 +898,11 @@ func (f argumentMatcher) String() string { // and false otherwise. // // Example: -// m.On("Do", MatchedBy(func(req *http.Request) bool { return req.Host == "example.com" })) // -// |fn|, must be a function accepting a single argument (of the expected type) -// which returns a bool. If |fn| doesn't match the required signature, +// m.On("Do", MatchedBy(func(req *http.Request) bool { return req.Host == "example.com" })) +// +// fn must be a function accepting a single argument (of the expected type) +// which returns a bool. If fn doesn't match the required signature, // MatchedBy() panics. func MatchedBy(fn interface{}) argumentMatcher { fnType := reflect.TypeOf(fn) @@ -979,20 +1005,17 @@ func (args Arguments) Diff(objects []interface{}) (string, int) { output = fmt.Sprintf("%s\t%d: FAIL: type %s != type %s - %s\n", output, i, expected.t.Name(), actualT.Name(), actualFmt) } case *FunctionalOptionsArgument: - t := expected.value - var name string - tValue := reflect.ValueOf(t) - if tValue.Len() > 0 { - name = "[]" + reflect.TypeOf(tValue.Index(0).Interface()).String() + if len(expected.values) > 0 { + name = "[]" + reflect.TypeOf(expected.values[0]).String() } - tName := reflect.TypeOf(t).Name() - if name != reflect.TypeOf(actual).String() && tValue.Len() != 0 { + const tName = "[]interface{}" + if name != reflect.TypeOf(actual).String() && len(expected.values) != 0 { differences++ output = fmt.Sprintf("%s\t%d: FAIL: type %s != type %s - %s\n", output, i, tName, reflect.TypeOf(actual).Name(), actualFmt) } else { - if ef, af := assertOpts(t, actual); ef == "" && af == "" { + if ef, af := assertOpts(expected.values, actual); ef == "" && af == "" { // match output = fmt.Sprintf("%s\t%d: PASS: %s == %s\n", output, i, tName, tName) } else { @@ -1092,7 +1115,7 @@ func (args Arguments) Error(index int) error { return nil } if s, ok = obj.(error); !ok { - panic(fmt.Sprintf("assert: arguments: Error(%d) failed because object wasn't correct type: %v", index, args.Get(index))) + panic(fmt.Sprintf("assert: arguments: Error(%d) failed because object wasn't correct type: %v", index, obj)) } return s } @@ -1181,32 +1204,38 @@ type tHelper interface { func assertOpts(expected, actual interface{}) (expectedFmt, actualFmt string) { expectedOpts := reflect.ValueOf(expected) actualOpts := reflect.ValueOf(actual) + + var expectedFuncs []*runtime.Func var expectedNames []string for i := 0; i < expectedOpts.Len(); i++ { - expectedNames = append(expectedNames, funcName(expectedOpts.Index(i).Interface())) + f := runtimeFunc(expectedOpts.Index(i).Interface()) + expectedFuncs = append(expectedFuncs, f) + expectedNames = append(expectedNames, funcName(f)) } + var actualFuncs []*runtime.Func var actualNames []string for i := 0; i < actualOpts.Len(); i++ { - actualNames = append(actualNames, funcName(actualOpts.Index(i).Interface())) + f := runtimeFunc(actualOpts.Index(i).Interface()) + actualFuncs = append(actualFuncs, f) + actualNames = append(actualNames, funcName(f)) } - if !assert.ObjectsAreEqual(expectedNames, actualNames) { + + if expectedOpts.Len() != actualOpts.Len() { expectedFmt = fmt.Sprintf("%v", expectedNames) actualFmt = fmt.Sprintf("%v", actualNames) return } for i := 0; i < expectedOpts.Len(); i++ { - expectedOpt := expectedOpts.Index(i).Interface() - actualOpt := actualOpts.Index(i).Interface() - - expectedFunc := expectedNames[i] - actualFunc := actualNames[i] - if expectedFunc != actualFunc { - expectedFmt = expectedFunc - actualFmt = actualFunc + if !isFuncSame(expectedFuncs[i], actualFuncs[i]) { + expectedFmt = expectedNames[i] + actualFmt = actualNames[i] return } + expectedOpt := expectedOpts.Index(i).Interface() + actualOpt := actualOpts.Index(i).Interface() + ot := reflect.TypeOf(expectedOpt) var expectedValues []reflect.Value var actualValues []reflect.Value @@ -1224,9 +1253,9 @@ func assertOpts(expected, actual interface{}) (expectedFmt, actualFmt string) { reflect.ValueOf(actualOpt).Call(actualValues) for i := 0; i < ot.NumIn(); i++ { - if !assert.ObjectsAreEqual(expectedValues[i].Interface(), actualValues[i].Interface()) { - expectedFmt = fmt.Sprintf("%s %+v", expectedNames[i], expectedValues[i].Interface()) - actualFmt = fmt.Sprintf("%s %+v", expectedNames[i], actualValues[i].Interface()) + if expectedArg, actualArg := expectedValues[i].Interface(), actualValues[i].Interface(); !assert.ObjectsAreEqual(expectedArg, actualArg) { + expectedFmt = fmt.Sprintf("%s(%T) -> %#v", expectedNames[i], expectedArg, expectedArg) + actualFmt = fmt.Sprintf("%s(%T) -> %#v", expectedNames[i], actualArg, actualArg) return } } @@ -1235,7 +1264,25 @@ func assertOpts(expected, actual interface{}) (expectedFmt, actualFmt string) { return "", "" } -func funcName(opt interface{}) string { - n := runtime.FuncForPC(reflect.ValueOf(opt).Pointer()).Name() - return strings.TrimSuffix(path.Base(n), path.Ext(n)) +func runtimeFunc(opt interface{}) *runtime.Func { + return runtime.FuncForPC(reflect.ValueOf(opt).Pointer()) +} + +func funcName(f *runtime.Func) string { + name := f.Name() + trimmed := strings.TrimSuffix(path.Base(name), path.Ext(name)) + splitted := strings.Split(trimmed, ".") + + if len(splitted) == 0 { + return trimmed + } + + return splitted[len(splitted)-1] +} + +func isFuncSame(f1, f2 *runtime.Func) bool { + f1File, f1Loc := f1.FileLine(f1.Entry()) + f2File, f2Loc := f2.FileLine(f2.Entry()) + + return f1File == f2File && f1Loc == f2Loc } diff --git a/go-controller/vendor/github.com/stretchr/testify/require/require.go b/go-controller/vendor/github.com/stretchr/testify/require/require.go index 506a82f807..d8921950d7 100644 --- a/go-controller/vendor/github.com/stretchr/testify/require/require.go +++ b/go-controller/vendor/github.com/stretchr/testify/require/require.go @@ -34,9 +34,9 @@ func Conditionf(t TestingT, comp assert.Comparison, msg string, args ...interfac // Contains asserts that the specified string, list(array, slice...) or map contains the // specified substring or element. // -// assert.Contains(t, "Hello World", "World") -// assert.Contains(t, ["Hello", "World"], "World") -// assert.Contains(t, {"Hello": "World"}, "Hello") +// require.Contains(t, "Hello World", "World") +// require.Contains(t, ["Hello", "World"], "World") +// require.Contains(t, {"Hello": "World"}, "Hello") func Contains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -50,9 +50,9 @@ func Contains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...int // Containsf asserts that the specified string, list(array, slice...) or map contains the // specified substring or element. // -// assert.Containsf(t, "Hello World", "World", "error message %s", "formatted") -// assert.Containsf(t, ["Hello", "World"], "World", "error message %s", "formatted") -// assert.Containsf(t, {"Hello": "World"}, "Hello", "error message %s", "formatted") +// require.Containsf(t, "Hello World", "World", "error message %s", "formatted") +// require.Containsf(t, ["Hello", "World"], "World", "error message %s", "formatted") +// require.Containsf(t, {"Hello": "World"}, "Hello", "error message %s", "formatted") func Containsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -91,7 +91,7 @@ func DirExistsf(t TestingT, path string, msg string, args ...interface{}) { // listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, // the number of appearances of each of them in both lists should match. // -// assert.ElementsMatch(t, [1, 3, 2, 3], [1, 3, 3, 2]) +// require.ElementsMatch(t, [1, 3, 2, 3], [1, 3, 3, 2]) func ElementsMatch(t TestingT, listA interface{}, listB interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -106,7 +106,7 @@ func ElementsMatch(t TestingT, listA interface{}, listB interface{}, msgAndArgs // listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, // the number of appearances of each of them in both lists should match. // -// assert.ElementsMatchf(t, [1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted") +// require.ElementsMatchf(t, [1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted") func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -120,7 +120,7 @@ func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string // Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either // a slice or a channel with len == 0. // -// assert.Empty(t, obj) +// require.Empty(t, obj) func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -134,7 +134,7 @@ func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) { // Emptyf asserts that the specified object is empty. I.e. nil, "", false, 0 or either // a slice or a channel with len == 0. // -// assert.Emptyf(t, obj, "error message %s", "formatted") +// require.Emptyf(t, obj, "error message %s", "formatted") func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -147,7 +147,7 @@ func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) { // Equal asserts that two objects are equal. // -// assert.Equal(t, 123, 123) +// require.Equal(t, 123, 123) // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). Function equality @@ -166,7 +166,7 @@ func Equal(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...i // and that it is equal to the provided error. // // actualObj, err := SomeFunction() -// assert.EqualError(t, err, expectedErrorString) +// require.EqualError(t, err, expectedErrorString) func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -181,7 +181,7 @@ func EqualError(t TestingT, theError error, errString string, msgAndArgs ...inte // and that it is equal to the provided error. // // actualObj, err := SomeFunction() -// assert.EqualErrorf(t, err, expectedErrorString, "error message %s", "formatted") +// require.EqualErrorf(t, err, expectedErrorString, "error message %s", "formatted") func EqualErrorf(t TestingT, theError error, errString string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -200,8 +200,8 @@ func EqualErrorf(t TestingT, theError error, errString string, msg string, args // Exported int // notExported int // } -// assert.EqualExportedValues(t, S{1, 2}, S{1, 3}) => true -// assert.EqualExportedValues(t, S{1, 2}, S{2, 3}) => false +// require.EqualExportedValues(t, S{1, 2}, S{1, 3}) => true +// require.EqualExportedValues(t, S{1, 2}, S{2, 3}) => false func EqualExportedValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -220,8 +220,8 @@ func EqualExportedValues(t TestingT, expected interface{}, actual interface{}, m // Exported int // notExported int // } -// assert.EqualExportedValuesf(t, S{1, 2}, S{1, 3}, "error message %s", "formatted") => true -// assert.EqualExportedValuesf(t, S{1, 2}, S{2, 3}, "error message %s", "formatted") => false +// require.EqualExportedValuesf(t, S{1, 2}, S{1, 3}, "error message %s", "formatted") => true +// require.EqualExportedValuesf(t, S{1, 2}, S{2, 3}, "error message %s", "formatted") => false func EqualExportedValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -232,10 +232,10 @@ func EqualExportedValuesf(t TestingT, expected interface{}, actual interface{}, t.FailNow() } -// EqualValues asserts that two objects are equal or convertible to the same types -// and equal. +// EqualValues asserts that two objects are equal or convertible to the larger +// type and equal. // -// assert.EqualValues(t, uint32(123), int32(123)) +// require.EqualValues(t, uint32(123), int32(123)) func EqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -246,10 +246,10 @@ func EqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArg t.FailNow() } -// EqualValuesf asserts that two objects are equal or convertible to the same types -// and equal. +// EqualValuesf asserts that two objects are equal or convertible to the larger +// type and equal. // -// assert.EqualValuesf(t, uint32(123), int32(123), "error message %s", "formatted") +// require.EqualValuesf(t, uint32(123), int32(123), "error message %s", "formatted") func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -262,7 +262,7 @@ func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg stri // Equalf asserts that two objects are equal. // -// assert.Equalf(t, 123, 123, "error message %s", "formatted") +// require.Equalf(t, 123, 123, "error message %s", "formatted") // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). Function equality @@ -280,8 +280,8 @@ func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, ar // Error asserts that a function returned an error (i.e. not `nil`). // // actualObj, err := SomeFunction() -// if assert.Error(t, err) { -// assert.Equal(t, expectedError, err) +// if require.Error(t, err) { +// require.Equal(t, expectedError, err) // } func Error(t TestingT, err error, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { @@ -321,7 +321,7 @@ func ErrorAsf(t TestingT, err error, target interface{}, msg string, args ...int // and that the error contains the specified substring. // // actualObj, err := SomeFunction() -// assert.ErrorContains(t, err, expectedErrorSubString) +// require.ErrorContains(t, err, expectedErrorSubString) func ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -336,7 +336,7 @@ func ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...in // and that the error contains the specified substring. // // actualObj, err := SomeFunction() -// assert.ErrorContainsf(t, err, expectedErrorSubString, "error message %s", "formatted") +// require.ErrorContainsf(t, err, expectedErrorSubString, "error message %s", "formatted") func ErrorContainsf(t TestingT, theError error, contains string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -374,8 +374,8 @@ func ErrorIsf(t TestingT, err error, target error, msg string, args ...interface // Errorf asserts that a function returned an error (i.e. not `nil`). // // actualObj, err := SomeFunction() -// if assert.Errorf(t, err, "error message %s", "formatted") { -// assert.Equal(t, expectedErrorf, err) +// if require.Errorf(t, err, "error message %s", "formatted") { +// require.Equal(t, expectedErrorf, err) // } func Errorf(t TestingT, err error, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { @@ -390,7 +390,7 @@ func Errorf(t TestingT, err error, msg string, args ...interface{}) { // Eventually asserts that given condition will be met in waitFor time, // periodically checking target function each tick. // -// assert.Eventually(t, func() bool { return true; }, time.Second, 10*time.Millisecond) +// require.Eventually(t, func() bool { return true; }, time.Second, 10*time.Millisecond) func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -415,10 +415,10 @@ func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick t // time.Sleep(8*time.Second) // externalValue = true // }() -// assert.EventuallyWithT(t, func(c *assert.CollectT) { +// require.EventuallyWithT(t, func(c *require.CollectT) { // // add assertions as needed; any assertion failure will fail the current tick -// assert.True(c, externalValue, "expected 'externalValue' to be true") -// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") +// require.True(c, externalValue, "expected 'externalValue' to be true") +// }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") func EventuallyWithT(t TestingT, condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -443,10 +443,10 @@ func EventuallyWithT(t TestingT, condition func(collect *assert.CollectT), waitF // time.Sleep(8*time.Second) // externalValue = true // }() -// assert.EventuallyWithTf(t, func(c *assert.CollectT, "error message %s", "formatted") { +// require.EventuallyWithTf(t, func(c *require.CollectT, "error message %s", "formatted") { // // add assertions as needed; any assertion failure will fail the current tick -// assert.True(c, externalValue, "expected 'externalValue' to be true") -// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") +// require.True(c, externalValue, "expected 'externalValue' to be true") +// }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") func EventuallyWithTf(t TestingT, condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -460,7 +460,7 @@ func EventuallyWithTf(t TestingT, condition func(collect *assert.CollectT), wait // Eventuallyf asserts that given condition will be met in waitFor time, // periodically checking target function each tick. // -// assert.Eventuallyf(t, func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") +// require.Eventuallyf(t, func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") func Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -473,7 +473,7 @@ func Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick // Exactly asserts that two objects are equal in value and type. // -// assert.Exactly(t, int32(123), int64(123)) +// require.Exactly(t, int32(123), int64(123)) func Exactly(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -486,7 +486,7 @@ func Exactly(t TestingT, expected interface{}, actual interface{}, msgAndArgs .. // Exactlyf asserts that two objects are equal in value and type. // -// assert.Exactlyf(t, int32(123), int64(123), "error message %s", "formatted") +// require.Exactlyf(t, int32(123), int64(123), "error message %s", "formatted") func Exactlyf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -543,7 +543,7 @@ func Failf(t TestingT, failureMessage string, msg string, args ...interface{}) { // False asserts that the specified value is false. // -// assert.False(t, myBool) +// require.False(t, myBool) func False(t TestingT, value bool, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -556,7 +556,7 @@ func False(t TestingT, value bool, msgAndArgs ...interface{}) { // Falsef asserts that the specified value is false. // -// assert.Falsef(t, myBool, "error message %s", "formatted") +// require.Falsef(t, myBool, "error message %s", "formatted") func Falsef(t TestingT, value bool, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -593,9 +593,9 @@ func FileExistsf(t TestingT, path string, msg string, args ...interface{}) { // Greater asserts that the first element is greater than the second // -// assert.Greater(t, 2, 1) -// assert.Greater(t, float64(2), float64(1)) -// assert.Greater(t, "b", "a") +// require.Greater(t, 2, 1) +// require.Greater(t, float64(2), float64(1)) +// require.Greater(t, "b", "a") func Greater(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -608,10 +608,10 @@ func Greater(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface // GreaterOrEqual asserts that the first element is greater than or equal to the second // -// assert.GreaterOrEqual(t, 2, 1) -// assert.GreaterOrEqual(t, 2, 2) -// assert.GreaterOrEqual(t, "b", "a") -// assert.GreaterOrEqual(t, "b", "b") +// require.GreaterOrEqual(t, 2, 1) +// require.GreaterOrEqual(t, 2, 2) +// require.GreaterOrEqual(t, "b", "a") +// require.GreaterOrEqual(t, "b", "b") func GreaterOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -624,10 +624,10 @@ func GreaterOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...in // GreaterOrEqualf asserts that the first element is greater than or equal to the second // -// assert.GreaterOrEqualf(t, 2, 1, "error message %s", "formatted") -// assert.GreaterOrEqualf(t, 2, 2, "error message %s", "formatted") -// assert.GreaterOrEqualf(t, "b", "a", "error message %s", "formatted") -// assert.GreaterOrEqualf(t, "b", "b", "error message %s", "formatted") +// require.GreaterOrEqualf(t, 2, 1, "error message %s", "formatted") +// require.GreaterOrEqualf(t, 2, 2, "error message %s", "formatted") +// require.GreaterOrEqualf(t, "b", "a", "error message %s", "formatted") +// require.GreaterOrEqualf(t, "b", "b", "error message %s", "formatted") func GreaterOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -640,9 +640,9 @@ func GreaterOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, arg // Greaterf asserts that the first element is greater than the second // -// assert.Greaterf(t, 2, 1, "error message %s", "formatted") -// assert.Greaterf(t, float64(2), float64(1), "error message %s", "formatted") -// assert.Greaterf(t, "b", "a", "error message %s", "formatted") +// require.Greaterf(t, 2, 1, "error message %s", "formatted") +// require.Greaterf(t, float64(2), float64(1), "error message %s", "formatted") +// require.Greaterf(t, "b", "a", "error message %s", "formatted") func Greaterf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -656,7 +656,7 @@ func Greaterf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...in // HTTPBodyContains asserts that a specified handler returns a // body that contains a string. // -// assert.HTTPBodyContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") +// require.HTTPBodyContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") // // Returns whether the assertion was successful (true) or not (false). func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) { @@ -672,7 +672,7 @@ func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method string, url s // HTTPBodyContainsf asserts that a specified handler returns a // body that contains a string. // -// assert.HTTPBodyContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") +// require.HTTPBodyContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) { @@ -688,7 +688,7 @@ func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url // HTTPBodyNotContains asserts that a specified handler returns a // body that does not contain a string. // -// assert.HTTPBodyNotContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") +// require.HTTPBodyNotContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") // // Returns whether the assertion was successful (true) or not (false). func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) { @@ -704,7 +704,7 @@ func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method string, ur // HTTPBodyNotContainsf asserts that a specified handler returns a // body that does not contain a string. // -// assert.HTTPBodyNotContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") +// require.HTTPBodyNotContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) { @@ -719,7 +719,7 @@ func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, u // HTTPError asserts that a specified handler returns an error status code. // -// assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// require.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). func HTTPError(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { @@ -734,7 +734,7 @@ func HTTPError(t TestingT, handler http.HandlerFunc, method string, url string, // HTTPErrorf asserts that a specified handler returns an error status code. // -// assert.HTTPErrorf(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// require.HTTPErrorf(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { @@ -749,7 +749,7 @@ func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, // HTTPRedirect asserts that a specified handler returns a redirect status code. // -// assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// require.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). func HTTPRedirect(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { @@ -764,7 +764,7 @@ func HTTPRedirect(t TestingT, handler http.HandlerFunc, method string, url strin // HTTPRedirectf asserts that a specified handler returns a redirect status code. // -// assert.HTTPRedirectf(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// require.HTTPRedirectf(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { @@ -779,7 +779,7 @@ func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url stri // HTTPStatusCode asserts that a specified handler returns a specified status code. // -// assert.HTTPStatusCode(t, myHandler, "GET", "/notImplemented", nil, 501) +// require.HTTPStatusCode(t, myHandler, "GET", "/notImplemented", nil, 501) // // Returns whether the assertion was successful (true) or not (false). func HTTPStatusCode(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msgAndArgs ...interface{}) { @@ -794,7 +794,7 @@ func HTTPStatusCode(t TestingT, handler http.HandlerFunc, method string, url str // HTTPStatusCodef asserts that a specified handler returns a specified status code. // -// assert.HTTPStatusCodef(t, myHandler, "GET", "/notImplemented", nil, 501, "error message %s", "formatted") +// require.HTTPStatusCodef(t, myHandler, "GET", "/notImplemented", nil, 501, "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). func HTTPStatusCodef(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msg string, args ...interface{}) { @@ -809,7 +809,7 @@ func HTTPStatusCodef(t TestingT, handler http.HandlerFunc, method string, url st // HTTPSuccess asserts that a specified handler returns a success status code. // -// assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil) +// require.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil) // // Returns whether the assertion was successful (true) or not (false). func HTTPSuccess(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { @@ -824,7 +824,7 @@ func HTTPSuccess(t TestingT, handler http.HandlerFunc, method string, url string // HTTPSuccessf asserts that a specified handler returns a success status code. // -// assert.HTTPSuccessf(t, myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted") +// require.HTTPSuccessf(t, myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { @@ -839,7 +839,7 @@ func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url strin // Implements asserts that an object is implemented by the specified interface. // -// assert.Implements(t, (*MyInterface)(nil), new(MyObject)) +// require.Implements(t, (*MyInterface)(nil), new(MyObject)) func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -852,7 +852,7 @@ func Implements(t TestingT, interfaceObject interface{}, object interface{}, msg // Implementsf asserts that an object is implemented by the specified interface. // -// assert.Implementsf(t, (*MyInterface)(nil), new(MyObject), "error message %s", "formatted") +// require.Implementsf(t, (*MyInterface)(nil), new(MyObject), "error message %s", "formatted") func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -865,7 +865,7 @@ func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, ms // InDelta asserts that the two numerals are within delta of each other. // -// assert.InDelta(t, math.Pi, 22/7.0, 0.01) +// require.InDelta(t, math.Pi, 22/7.0, 0.01) func InDelta(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -922,7 +922,7 @@ func InDeltaSlicef(t TestingT, expected interface{}, actual interface{}, delta f // InDeltaf asserts that the two numerals are within delta of each other. // -// assert.InDeltaf(t, math.Pi, 22/7.0, 0.01, "error message %s", "formatted") +// require.InDeltaf(t, math.Pi, 22/7.0, 0.01, "error message %s", "formatted") func InDeltaf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -979,9 +979,9 @@ func InEpsilonf(t TestingT, expected interface{}, actual interface{}, epsilon fl // IsDecreasing asserts that the collection is decreasing // -// assert.IsDecreasing(t, []int{2, 1, 0}) -// assert.IsDecreasing(t, []float{2, 1}) -// assert.IsDecreasing(t, []string{"b", "a"}) +// require.IsDecreasing(t, []int{2, 1, 0}) +// require.IsDecreasing(t, []float{2, 1}) +// require.IsDecreasing(t, []string{"b", "a"}) func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -994,9 +994,9 @@ func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { // IsDecreasingf asserts that the collection is decreasing // -// assert.IsDecreasingf(t, []int{2, 1, 0}, "error message %s", "formatted") -// assert.IsDecreasingf(t, []float{2, 1}, "error message %s", "formatted") -// assert.IsDecreasingf(t, []string{"b", "a"}, "error message %s", "formatted") +// require.IsDecreasingf(t, []int{2, 1, 0}, "error message %s", "formatted") +// require.IsDecreasingf(t, []float{2, 1}, "error message %s", "formatted") +// require.IsDecreasingf(t, []string{"b", "a"}, "error message %s", "formatted") func IsDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1009,9 +1009,9 @@ func IsDecreasingf(t TestingT, object interface{}, msg string, args ...interface // IsIncreasing asserts that the collection is increasing // -// assert.IsIncreasing(t, []int{1, 2, 3}) -// assert.IsIncreasing(t, []float{1, 2}) -// assert.IsIncreasing(t, []string{"a", "b"}) +// require.IsIncreasing(t, []int{1, 2, 3}) +// require.IsIncreasing(t, []float{1, 2}) +// require.IsIncreasing(t, []string{"a", "b"}) func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1024,9 +1024,9 @@ func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { // IsIncreasingf asserts that the collection is increasing // -// assert.IsIncreasingf(t, []int{1, 2, 3}, "error message %s", "formatted") -// assert.IsIncreasingf(t, []float{1, 2}, "error message %s", "formatted") -// assert.IsIncreasingf(t, []string{"a", "b"}, "error message %s", "formatted") +// require.IsIncreasingf(t, []int{1, 2, 3}, "error message %s", "formatted") +// require.IsIncreasingf(t, []float{1, 2}, "error message %s", "formatted") +// require.IsIncreasingf(t, []string{"a", "b"}, "error message %s", "formatted") func IsIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1039,9 +1039,9 @@ func IsIncreasingf(t TestingT, object interface{}, msg string, args ...interface // IsNonDecreasing asserts that the collection is not decreasing // -// assert.IsNonDecreasing(t, []int{1, 1, 2}) -// assert.IsNonDecreasing(t, []float{1, 2}) -// assert.IsNonDecreasing(t, []string{"a", "b"}) +// require.IsNonDecreasing(t, []int{1, 1, 2}) +// require.IsNonDecreasing(t, []float{1, 2}) +// require.IsNonDecreasing(t, []string{"a", "b"}) func IsNonDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1054,9 +1054,9 @@ func IsNonDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) // IsNonDecreasingf asserts that the collection is not decreasing // -// assert.IsNonDecreasingf(t, []int{1, 1, 2}, "error message %s", "formatted") -// assert.IsNonDecreasingf(t, []float{1, 2}, "error message %s", "formatted") -// assert.IsNonDecreasingf(t, []string{"a", "b"}, "error message %s", "formatted") +// require.IsNonDecreasingf(t, []int{1, 1, 2}, "error message %s", "formatted") +// require.IsNonDecreasingf(t, []float{1, 2}, "error message %s", "formatted") +// require.IsNonDecreasingf(t, []string{"a", "b"}, "error message %s", "formatted") func IsNonDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1069,9 +1069,9 @@ func IsNonDecreasingf(t TestingT, object interface{}, msg string, args ...interf // IsNonIncreasing asserts that the collection is not increasing // -// assert.IsNonIncreasing(t, []int{2, 1, 1}) -// assert.IsNonIncreasing(t, []float{2, 1}) -// assert.IsNonIncreasing(t, []string{"b", "a"}) +// require.IsNonIncreasing(t, []int{2, 1, 1}) +// require.IsNonIncreasing(t, []float{2, 1}) +// require.IsNonIncreasing(t, []string{"b", "a"}) func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1084,9 +1084,9 @@ func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) // IsNonIncreasingf asserts that the collection is not increasing // -// assert.IsNonIncreasingf(t, []int{2, 1, 1}, "error message %s", "formatted") -// assert.IsNonIncreasingf(t, []float{2, 1}, "error message %s", "formatted") -// assert.IsNonIncreasingf(t, []string{"b", "a"}, "error message %s", "formatted") +// require.IsNonIncreasingf(t, []int{2, 1, 1}, "error message %s", "formatted") +// require.IsNonIncreasingf(t, []float{2, 1}, "error message %s", "formatted") +// require.IsNonIncreasingf(t, []string{"b", "a"}, "error message %s", "formatted") func IsNonIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1121,7 +1121,7 @@ func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg strin // JSONEq asserts that two JSON strings are equivalent. // -// assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) +// require.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1134,7 +1134,7 @@ func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{ // JSONEqf asserts that two JSON strings are equivalent. // -// assert.JSONEqf(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted") +// require.JSONEqf(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted") func JSONEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1148,7 +1148,7 @@ func JSONEqf(t TestingT, expected string, actual string, msg string, args ...int // Len asserts that the specified object has specific length. // Len also fails if the object has a type that len() not accept. // -// assert.Len(t, mySlice, 3) +// require.Len(t, mySlice, 3) func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1162,7 +1162,7 @@ func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) // Lenf asserts that the specified object has specific length. // Lenf also fails if the object has a type that len() not accept. // -// assert.Lenf(t, mySlice, 3, "error message %s", "formatted") +// require.Lenf(t, mySlice, 3, "error message %s", "formatted") func Lenf(t TestingT, object interface{}, length int, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1175,9 +1175,9 @@ func Lenf(t TestingT, object interface{}, length int, msg string, args ...interf // Less asserts that the first element is less than the second // -// assert.Less(t, 1, 2) -// assert.Less(t, float64(1), float64(2)) -// assert.Less(t, "a", "b") +// require.Less(t, 1, 2) +// require.Less(t, float64(1), float64(2)) +// require.Less(t, "a", "b") func Less(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1190,10 +1190,10 @@ func Less(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) // LessOrEqual asserts that the first element is less than or equal to the second // -// assert.LessOrEqual(t, 1, 2) -// assert.LessOrEqual(t, 2, 2) -// assert.LessOrEqual(t, "a", "b") -// assert.LessOrEqual(t, "b", "b") +// require.LessOrEqual(t, 1, 2) +// require.LessOrEqual(t, 2, 2) +// require.LessOrEqual(t, "a", "b") +// require.LessOrEqual(t, "b", "b") func LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1206,10 +1206,10 @@ func LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...inter // LessOrEqualf asserts that the first element is less than or equal to the second // -// assert.LessOrEqualf(t, 1, 2, "error message %s", "formatted") -// assert.LessOrEqualf(t, 2, 2, "error message %s", "formatted") -// assert.LessOrEqualf(t, "a", "b", "error message %s", "formatted") -// assert.LessOrEqualf(t, "b", "b", "error message %s", "formatted") +// require.LessOrEqualf(t, 1, 2, "error message %s", "formatted") +// require.LessOrEqualf(t, 2, 2, "error message %s", "formatted") +// require.LessOrEqualf(t, "a", "b", "error message %s", "formatted") +// require.LessOrEqualf(t, "b", "b", "error message %s", "formatted") func LessOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1222,9 +1222,9 @@ func LessOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args . // Lessf asserts that the first element is less than the second // -// assert.Lessf(t, 1, 2, "error message %s", "formatted") -// assert.Lessf(t, float64(1), float64(2), "error message %s", "formatted") -// assert.Lessf(t, "a", "b", "error message %s", "formatted") +// require.Lessf(t, 1, 2, "error message %s", "formatted") +// require.Lessf(t, float64(1), float64(2), "error message %s", "formatted") +// require.Lessf(t, "a", "b", "error message %s", "formatted") func Lessf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1237,8 +1237,8 @@ func Lessf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...inter // Negative asserts that the specified element is negative // -// assert.Negative(t, -1) -// assert.Negative(t, -1.23) +// require.Negative(t, -1) +// require.Negative(t, -1.23) func Negative(t TestingT, e interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1251,8 +1251,8 @@ func Negative(t TestingT, e interface{}, msgAndArgs ...interface{}) { // Negativef asserts that the specified element is negative // -// assert.Negativef(t, -1, "error message %s", "formatted") -// assert.Negativef(t, -1.23, "error message %s", "formatted") +// require.Negativef(t, -1, "error message %s", "formatted") +// require.Negativef(t, -1.23, "error message %s", "formatted") func Negativef(t TestingT, e interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1266,7 +1266,7 @@ func Negativef(t TestingT, e interface{}, msg string, args ...interface{}) { // Never asserts that the given condition doesn't satisfy in waitFor time, // periodically checking the target function each tick. // -// assert.Never(t, func() bool { return false; }, time.Second, 10*time.Millisecond) +// require.Never(t, func() bool { return false; }, time.Second, 10*time.Millisecond) func Never(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1280,7 +1280,7 @@ func Never(t TestingT, condition func() bool, waitFor time.Duration, tick time.D // Neverf asserts that the given condition doesn't satisfy in waitFor time, // periodically checking the target function each tick. // -// assert.Neverf(t, func() bool { return false; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") +// require.Neverf(t, func() bool { return false; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") func Neverf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1293,7 +1293,7 @@ func Neverf(t TestingT, condition func() bool, waitFor time.Duration, tick time. // Nil asserts that the specified object is nil. // -// assert.Nil(t, err) +// require.Nil(t, err) func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1306,7 +1306,7 @@ func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) { // Nilf asserts that the specified object is nil. // -// assert.Nilf(t, err, "error message %s", "formatted") +// require.Nilf(t, err, "error message %s", "formatted") func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1344,8 +1344,8 @@ func NoDirExistsf(t TestingT, path string, msg string, args ...interface{}) { // NoError asserts that a function returned no error (i.e. `nil`). // // actualObj, err := SomeFunction() -// if assert.NoError(t, err) { -// assert.Equal(t, expectedObj, actualObj) +// if require.NoError(t, err) { +// require.Equal(t, expectedObj, actualObj) // } func NoError(t TestingT, err error, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { @@ -1360,8 +1360,8 @@ func NoError(t TestingT, err error, msgAndArgs ...interface{}) { // NoErrorf asserts that a function returned no error (i.e. `nil`). // // actualObj, err := SomeFunction() -// if assert.NoErrorf(t, err, "error message %s", "formatted") { -// assert.Equal(t, expectedObj, actualObj) +// if require.NoErrorf(t, err, "error message %s", "formatted") { +// require.Equal(t, expectedObj, actualObj) // } func NoErrorf(t TestingT, err error, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { @@ -1400,9 +1400,9 @@ func NoFileExistsf(t TestingT, path string, msg string, args ...interface{}) { // NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the // specified substring or element. // -// assert.NotContains(t, "Hello World", "Earth") -// assert.NotContains(t, ["Hello", "World"], "Earth") -// assert.NotContains(t, {"Hello": "World"}, "Earth") +// require.NotContains(t, "Hello World", "Earth") +// require.NotContains(t, ["Hello", "World"], "Earth") +// require.NotContains(t, {"Hello": "World"}, "Earth") func NotContains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1416,9 +1416,9 @@ func NotContains(t TestingT, s interface{}, contains interface{}, msgAndArgs ... // NotContainsf asserts that the specified string, list(array, slice...) or map does NOT contain the // specified substring or element. // -// assert.NotContainsf(t, "Hello World", "Earth", "error message %s", "formatted") -// assert.NotContainsf(t, ["Hello", "World"], "Earth", "error message %s", "formatted") -// assert.NotContainsf(t, {"Hello": "World"}, "Earth", "error message %s", "formatted") +// require.NotContainsf(t, "Hello World", "Earth", "error message %s", "formatted") +// require.NotContainsf(t, ["Hello", "World"], "Earth", "error message %s", "formatted") +// require.NotContainsf(t, {"Hello": "World"}, "Earth", "error message %s", "formatted") func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1429,11 +1429,51 @@ func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, a t.FailNow() } +// NotElementsMatch asserts that the specified listA(array, slice...) is NOT equal to specified +// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, +// the number of appearances of each of them in both lists should not match. +// This is an inverse of ElementsMatch. +// +// require.NotElementsMatch(t, [1, 1, 2, 3], [1, 1, 2, 3]) -> false +// +// require.NotElementsMatch(t, [1, 1, 2, 3], [1, 2, 3]) -> true +// +// require.NotElementsMatch(t, [1, 2, 3], [1, 2, 4]) -> true +func NotElementsMatch(t TestingT, listA interface{}, listB interface{}, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if assert.NotElementsMatch(t, listA, listB, msgAndArgs...) { + return + } + t.FailNow() +} + +// NotElementsMatchf asserts that the specified listA(array, slice...) is NOT equal to specified +// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, +// the number of appearances of each of them in both lists should not match. +// This is an inverse of ElementsMatch. +// +// require.NotElementsMatchf(t, [1, 1, 2, 3], [1, 1, 2, 3], "error message %s", "formatted") -> false +// +// require.NotElementsMatchf(t, [1, 1, 2, 3], [1, 2, 3], "error message %s", "formatted") -> true +// +// require.NotElementsMatchf(t, [1, 2, 3], [1, 2, 4], "error message %s", "formatted") -> true +func NotElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if assert.NotElementsMatchf(t, listA, listB, msg, args...) { + return + } + t.FailNow() +} + // NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either // a slice or a channel with len == 0. // -// if assert.NotEmpty(t, obj) { -// assert.Equal(t, "two", obj[1]) +// if require.NotEmpty(t, obj) { +// require.Equal(t, "two", obj[1]) // } func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { @@ -1448,8 +1488,8 @@ func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) { // NotEmptyf asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either // a slice or a channel with len == 0. // -// if assert.NotEmptyf(t, obj, "error message %s", "formatted") { -// assert.Equal(t, "two", obj[1]) +// if require.NotEmptyf(t, obj, "error message %s", "formatted") { +// require.Equal(t, "two", obj[1]) // } func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { @@ -1463,7 +1503,7 @@ func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) // NotEqual asserts that the specified values are NOT equal. // -// assert.NotEqual(t, obj1, obj2) +// require.NotEqual(t, obj1, obj2) // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). @@ -1479,7 +1519,7 @@ func NotEqual(t TestingT, expected interface{}, actual interface{}, msgAndArgs . // NotEqualValues asserts that two objects are not equal even when converted to the same type // -// assert.NotEqualValues(t, obj1, obj2) +// require.NotEqualValues(t, obj1, obj2) func NotEqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1492,7 +1532,7 @@ func NotEqualValues(t TestingT, expected interface{}, actual interface{}, msgAnd // NotEqualValuesf asserts that two objects are not equal even when converted to the same type // -// assert.NotEqualValuesf(t, obj1, obj2, "error message %s", "formatted") +// require.NotEqualValuesf(t, obj1, obj2, "error message %s", "formatted") func NotEqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1505,7 +1545,7 @@ func NotEqualValuesf(t TestingT, expected interface{}, actual interface{}, msg s // NotEqualf asserts that the specified values are NOT equal. // -// assert.NotEqualf(t, obj1, obj2, "error message %s", "formatted") +// require.NotEqualf(t, obj1, obj2, "error message %s", "formatted") // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). @@ -1519,7 +1559,31 @@ func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string, t.FailNow() } -// NotErrorIs asserts that at none of the errors in err's chain matches target. +// NotErrorAs asserts that none of the errors in err's chain matches target, +// but if so, sets target to that error value. +func NotErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if assert.NotErrorAs(t, err, target, msgAndArgs...) { + return + } + t.FailNow() +} + +// NotErrorAsf asserts that none of the errors in err's chain matches target, +// but if so, sets target to that error value. +func NotErrorAsf(t TestingT, err error, target interface{}, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if assert.NotErrorAsf(t, err, target, msg, args...) { + return + } + t.FailNow() +} + +// NotErrorIs asserts that none of the errors in err's chain matches target. // This is a wrapper for errors.Is. func NotErrorIs(t TestingT, err error, target error, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { @@ -1531,7 +1595,7 @@ func NotErrorIs(t TestingT, err error, target error, msgAndArgs ...interface{}) t.FailNow() } -// NotErrorIsf asserts that at none of the errors in err's chain matches target. +// NotErrorIsf asserts that none of the errors in err's chain matches target. // This is a wrapper for errors.Is. func NotErrorIsf(t TestingT, err error, target error, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { @@ -1545,7 +1609,7 @@ func NotErrorIsf(t TestingT, err error, target error, msg string, args ...interf // NotImplements asserts that an object does not implement the specified interface. // -// assert.NotImplements(t, (*MyInterface)(nil), new(MyObject)) +// require.NotImplements(t, (*MyInterface)(nil), new(MyObject)) func NotImplements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1558,7 +1622,7 @@ func NotImplements(t TestingT, interfaceObject interface{}, object interface{}, // NotImplementsf asserts that an object does not implement the specified interface. // -// assert.NotImplementsf(t, (*MyInterface)(nil), new(MyObject), "error message %s", "formatted") +// require.NotImplementsf(t, (*MyInterface)(nil), new(MyObject), "error message %s", "formatted") func NotImplementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1571,7 +1635,7 @@ func NotImplementsf(t TestingT, interfaceObject interface{}, object interface{}, // NotNil asserts that the specified object is not nil. // -// assert.NotNil(t, err) +// require.NotNil(t, err) func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1584,7 +1648,7 @@ func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) { // NotNilf asserts that the specified object is not nil. // -// assert.NotNilf(t, err, "error message %s", "formatted") +// require.NotNilf(t, err, "error message %s", "formatted") func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1597,7 +1661,7 @@ func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) { // NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. // -// assert.NotPanics(t, func(){ RemainCalm() }) +// require.NotPanics(t, func(){ RemainCalm() }) func NotPanics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1610,7 +1674,7 @@ func NotPanics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) { // NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic. // -// assert.NotPanicsf(t, func(){ RemainCalm() }, "error message %s", "formatted") +// require.NotPanicsf(t, func(){ RemainCalm() }, "error message %s", "formatted") func NotPanicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1623,8 +1687,8 @@ func NotPanicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interfac // NotRegexp asserts that a specified regexp does not match a string. // -// assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting") -// assert.NotRegexp(t, "^start", "it's not starting") +// require.NotRegexp(t, regexp.MustCompile("starts"), "it's starting") +// require.NotRegexp(t, "^start", "it's not starting") func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1637,8 +1701,8 @@ func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interf // NotRegexpf asserts that a specified regexp does not match a string. // -// assert.NotRegexpf(t, regexp.MustCompile("starts"), "it's starting", "error message %s", "formatted") -// assert.NotRegexpf(t, "^start", "it's not starting", "error message %s", "formatted") +// require.NotRegexpf(t, regexp.MustCompile("starts"), "it's starting", "error message %s", "formatted") +// require.NotRegexpf(t, "^start", "it's not starting", "error message %s", "formatted") func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1651,7 +1715,7 @@ func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args .. // NotSame asserts that two pointers do not reference the same object. // -// assert.NotSame(t, ptr1, ptr2) +// require.NotSame(t, ptr1, ptr2) // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. @@ -1667,7 +1731,7 @@ func NotSame(t TestingT, expected interface{}, actual interface{}, msgAndArgs .. // NotSamef asserts that two pointers do not reference the same object. // -// assert.NotSamef(t, ptr1, ptr2, "error message %s", "formatted") +// require.NotSamef(t, ptr1, ptr2, "error message %s", "formatted") // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. @@ -1685,8 +1749,8 @@ func NotSamef(t TestingT, expected interface{}, actual interface{}, msg string, // contain all elements given in the specified subset list(array, slice...) or // map. // -// assert.NotSubset(t, [1, 3, 4], [1, 2]) -// assert.NotSubset(t, {"x": 1, "y": 2}, {"z": 3}) +// require.NotSubset(t, [1, 3, 4], [1, 2]) +// require.NotSubset(t, {"x": 1, "y": 2}, {"z": 3}) func NotSubset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1701,8 +1765,8 @@ func NotSubset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...i // contain all elements given in the specified subset list(array, slice...) or // map. // -// assert.NotSubsetf(t, [1, 3, 4], [1, 2], "error message %s", "formatted") -// assert.NotSubsetf(t, {"x": 1, "y": 2}, {"z": 3}, "error message %s", "formatted") +// require.NotSubsetf(t, [1, 3, 4], [1, 2], "error message %s", "formatted") +// require.NotSubsetf(t, {"x": 1, "y": 2}, {"z": 3}, "error message %s", "formatted") func NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1737,7 +1801,7 @@ func NotZerof(t TestingT, i interface{}, msg string, args ...interface{}) { // Panics asserts that the code inside the specified PanicTestFunc panics. // -// assert.Panics(t, func(){ GoCrazy() }) +// require.Panics(t, func(){ GoCrazy() }) func Panics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1752,7 +1816,7 @@ func Panics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) { // panics, and that the recovered panic value is an error that satisfies the // EqualError comparison. // -// assert.PanicsWithError(t, "crazy error", func(){ GoCrazy() }) +// require.PanicsWithError(t, "crazy error", func(){ GoCrazy() }) func PanicsWithError(t TestingT, errString string, f assert.PanicTestFunc, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1767,7 +1831,7 @@ func PanicsWithError(t TestingT, errString string, f assert.PanicTestFunc, msgAn // panics, and that the recovered panic value is an error that satisfies the // EqualError comparison. // -// assert.PanicsWithErrorf(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") +// require.PanicsWithErrorf(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") func PanicsWithErrorf(t TestingT, errString string, f assert.PanicTestFunc, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1781,7 +1845,7 @@ func PanicsWithErrorf(t TestingT, errString string, f assert.PanicTestFunc, msg // PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that // the recovered panic value equals the expected panic value. // -// assert.PanicsWithValue(t, "crazy error", func(){ GoCrazy() }) +// require.PanicsWithValue(t, "crazy error", func(){ GoCrazy() }) func PanicsWithValue(t TestingT, expected interface{}, f assert.PanicTestFunc, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1795,7 +1859,7 @@ func PanicsWithValue(t TestingT, expected interface{}, f assert.PanicTestFunc, m // PanicsWithValuef asserts that the code inside the specified PanicTestFunc panics, and that // the recovered panic value equals the expected panic value. // -// assert.PanicsWithValuef(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") +// require.PanicsWithValuef(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") func PanicsWithValuef(t TestingT, expected interface{}, f assert.PanicTestFunc, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1808,7 +1872,7 @@ func PanicsWithValuef(t TestingT, expected interface{}, f assert.PanicTestFunc, // Panicsf asserts that the code inside the specified PanicTestFunc panics. // -// assert.Panicsf(t, func(){ GoCrazy() }, "error message %s", "formatted") +// require.Panicsf(t, func(){ GoCrazy() }, "error message %s", "formatted") func Panicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1821,8 +1885,8 @@ func Panicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interface{} // Positive asserts that the specified element is positive // -// assert.Positive(t, 1) -// assert.Positive(t, 1.23) +// require.Positive(t, 1) +// require.Positive(t, 1.23) func Positive(t TestingT, e interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1835,8 +1899,8 @@ func Positive(t TestingT, e interface{}, msgAndArgs ...interface{}) { // Positivef asserts that the specified element is positive // -// assert.Positivef(t, 1, "error message %s", "formatted") -// assert.Positivef(t, 1.23, "error message %s", "formatted") +// require.Positivef(t, 1, "error message %s", "formatted") +// require.Positivef(t, 1.23, "error message %s", "formatted") func Positivef(t TestingT, e interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1849,8 +1913,8 @@ func Positivef(t TestingT, e interface{}, msg string, args ...interface{}) { // Regexp asserts that a specified regexp matches a string. // -// assert.Regexp(t, regexp.MustCompile("start"), "it's starting") -// assert.Regexp(t, "start...$", "it's not starting") +// require.Regexp(t, regexp.MustCompile("start"), "it's starting") +// require.Regexp(t, "start...$", "it's not starting") func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1863,8 +1927,8 @@ func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface // Regexpf asserts that a specified regexp matches a string. // -// assert.Regexpf(t, regexp.MustCompile("start"), "it's starting", "error message %s", "formatted") -// assert.Regexpf(t, "start...$", "it's not starting", "error message %s", "formatted") +// require.Regexpf(t, regexp.MustCompile("start"), "it's starting", "error message %s", "formatted") +// require.Regexpf(t, "start...$", "it's not starting", "error message %s", "formatted") func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1877,7 +1941,7 @@ func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...in // Same asserts that two pointers reference the same object. // -// assert.Same(t, ptr1, ptr2) +// require.Same(t, ptr1, ptr2) // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. @@ -1893,7 +1957,7 @@ func Same(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...in // Samef asserts that two pointers reference the same object. // -// assert.Samef(t, ptr1, ptr2, "error message %s", "formatted") +// require.Samef(t, ptr1, ptr2, "error message %s", "formatted") // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. @@ -1910,8 +1974,8 @@ func Samef(t TestingT, expected interface{}, actual interface{}, msg string, arg // Subset asserts that the specified list(array, slice...) or map contains all // elements given in the specified subset list(array, slice...) or map. // -// assert.Subset(t, [1, 2, 3], [1, 2]) -// assert.Subset(t, {"x": 1, "y": 2}, {"x": 1}) +// require.Subset(t, [1, 2, 3], [1, 2]) +// require.Subset(t, {"x": 1, "y": 2}, {"x": 1}) func Subset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1925,8 +1989,8 @@ func Subset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...inte // Subsetf asserts that the specified list(array, slice...) or map contains all // elements given in the specified subset list(array, slice...) or map. // -// assert.Subsetf(t, [1, 2, 3], [1, 2], "error message %s", "formatted") -// assert.Subsetf(t, {"x": 1, "y": 2}, {"x": 1}, "error message %s", "formatted") +// require.Subsetf(t, [1, 2, 3], [1, 2], "error message %s", "formatted") +// require.Subsetf(t, {"x": 1, "y": 2}, {"x": 1}, "error message %s", "formatted") func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1939,7 +2003,7 @@ func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args // True asserts that the specified value is true. // -// assert.True(t, myBool) +// require.True(t, myBool) func True(t TestingT, value bool, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1952,7 +2016,7 @@ func True(t TestingT, value bool, msgAndArgs ...interface{}) { // Truef asserts that the specified value is true. // -// assert.Truef(t, myBool, "error message %s", "formatted") +// require.Truef(t, myBool, "error message %s", "formatted") func Truef(t TestingT, value bool, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1965,7 +2029,7 @@ func Truef(t TestingT, value bool, msg string, args ...interface{}) { // WithinDuration asserts that the two times are within duration delta of each other. // -// assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second) +// require.WithinDuration(t, time.Now(), time.Now(), 10*time.Second) func WithinDuration(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1978,7 +2042,7 @@ func WithinDuration(t TestingT, expected time.Time, actual time.Time, delta time // WithinDurationf asserts that the two times are within duration delta of each other. // -// assert.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted") +// require.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted") func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1991,7 +2055,7 @@ func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta tim // WithinRange asserts that a time is within a time range (inclusive). // -// assert.WithinRange(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second)) +// require.WithinRange(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second)) func WithinRange(t TestingT, actual time.Time, start time.Time, end time.Time, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -2004,7 +2068,7 @@ func WithinRange(t TestingT, actual time.Time, start time.Time, end time.Time, m // WithinRangef asserts that a time is within a time range (inclusive). // -// assert.WithinRangef(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), "error message %s", "formatted") +// require.WithinRangef(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), "error message %s", "formatted") func WithinRangef(t TestingT, actual time.Time, start time.Time, end time.Time, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() diff --git a/go-controller/vendor/github.com/stretchr/testify/require/require.go.tmpl b/go-controller/vendor/github.com/stretchr/testify/require/require.go.tmpl index 55e42ddebd..8b32836850 100644 --- a/go-controller/vendor/github.com/stretchr/testify/require/require.go.tmpl +++ b/go-controller/vendor/github.com/stretchr/testify/require/require.go.tmpl @@ -1,4 +1,4 @@ -{{.Comment}} +{{ replace .Comment "assert." "require."}} func {{.DocInfo.Name}}(t TestingT, {{.Params}}) { if h, ok := t.(tHelper); ok { h.Helper() } if assert.{{.DocInfo.Name}}(t, {{.ForwardedParams}}) { return } diff --git a/go-controller/vendor/github.com/stretchr/testify/require/require_forward.go b/go-controller/vendor/github.com/stretchr/testify/require/require_forward.go index eee8310a5f..1bd87304f4 100644 --- a/go-controller/vendor/github.com/stretchr/testify/require/require_forward.go +++ b/go-controller/vendor/github.com/stretchr/testify/require/require_forward.go @@ -187,8 +187,8 @@ func (a *Assertions) EqualExportedValuesf(expected interface{}, actual interface EqualExportedValuesf(a.t, expected, actual, msg, args...) } -// EqualValues asserts that two objects are equal or convertible to the same types -// and equal. +// EqualValues asserts that two objects are equal or convertible to the larger +// type and equal. // // a.EqualValues(uint32(123), int32(123)) func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) { @@ -198,8 +198,8 @@ func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAn EqualValues(a.t, expected, actual, msgAndArgs...) } -// EqualValuesf asserts that two objects are equal or convertible to the same types -// and equal. +// EqualValuesf asserts that two objects are equal or convertible to the larger +// type and equal. // // a.EqualValuesf(uint32(123), int32(123), "error message %s", "formatted") func (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) { @@ -337,7 +337,7 @@ func (a *Assertions) Eventually(condition func() bool, waitFor time.Duration, ti // a.EventuallyWithT(func(c *assert.CollectT) { // // add assertions as needed; any assertion failure will fail the current tick // assert.True(c, externalValue, "expected 'externalValue' to be true") -// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") +// }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") func (a *Assertions) EventuallyWithT(condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -362,7 +362,7 @@ func (a *Assertions) EventuallyWithT(condition func(collect *assert.CollectT), w // a.EventuallyWithTf(func(c *assert.CollectT, "error message %s", "formatted") { // // add assertions as needed; any assertion failure will fail the current tick // assert.True(c, externalValue, "expected 'externalValue' to be true") -// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") +// }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") func (a *Assertions) EventuallyWithTf(condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1129,6 +1129,40 @@ func (a *Assertions) NotContainsf(s interface{}, contains interface{}, msg strin NotContainsf(a.t, s, contains, msg, args...) } +// NotElementsMatch asserts that the specified listA(array, slice...) is NOT equal to specified +// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, +// the number of appearances of each of them in both lists should not match. +// This is an inverse of ElementsMatch. +// +// a.NotElementsMatch([1, 1, 2, 3], [1, 1, 2, 3]) -> false +// +// a.NotElementsMatch([1, 1, 2, 3], [1, 2, 3]) -> true +// +// a.NotElementsMatch([1, 2, 3], [1, 2, 4]) -> true +func (a *Assertions) NotElementsMatch(listA interface{}, listB interface{}, msgAndArgs ...interface{}) { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + NotElementsMatch(a.t, listA, listB, msgAndArgs...) +} + +// NotElementsMatchf asserts that the specified listA(array, slice...) is NOT equal to specified +// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, +// the number of appearances of each of them in both lists should not match. +// This is an inverse of ElementsMatch. +// +// a.NotElementsMatchf([1, 1, 2, 3], [1, 1, 2, 3], "error message %s", "formatted") -> false +// +// a.NotElementsMatchf([1, 1, 2, 3], [1, 2, 3], "error message %s", "formatted") -> true +// +// a.NotElementsMatchf([1, 2, 3], [1, 2, 4], "error message %s", "formatted") -> true +func (a *Assertions) NotElementsMatchf(listA interface{}, listB interface{}, msg string, args ...interface{}) { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + NotElementsMatchf(a.t, listA, listB, msg, args...) +} + // NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either // a slice or a channel with len == 0. // @@ -1201,7 +1235,25 @@ func (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg str NotEqualf(a.t, expected, actual, msg, args...) } -// NotErrorIs asserts that at none of the errors in err's chain matches target. +// NotErrorAs asserts that none of the errors in err's chain matches target, +// but if so, sets target to that error value. +func (a *Assertions) NotErrorAs(err error, target interface{}, msgAndArgs ...interface{}) { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + NotErrorAs(a.t, err, target, msgAndArgs...) +} + +// NotErrorAsf asserts that none of the errors in err's chain matches target, +// but if so, sets target to that error value. +func (a *Assertions) NotErrorAsf(err error, target interface{}, msg string, args ...interface{}) { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + NotErrorAsf(a.t, err, target, msg, args...) +} + +// NotErrorIs asserts that none of the errors in err's chain matches target. // This is a wrapper for errors.Is. func (a *Assertions) NotErrorIs(err error, target error, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { @@ -1210,7 +1262,7 @@ func (a *Assertions) NotErrorIs(err error, target error, msgAndArgs ...interface NotErrorIs(a.t, err, target, msgAndArgs...) } -// NotErrorIsf asserts that at none of the errors in err's chain matches target. +// NotErrorIsf asserts that none of the errors in err's chain matches target. // This is a wrapper for errors.Is. func (a *Assertions) NotErrorIsf(err error, target error, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { diff --git a/go-controller/vendor/github.com/stretchr/testify/require/requirements.go b/go-controller/vendor/github.com/stretchr/testify/require/requirements.go index 91772dfeb9..6b7ce929eb 100644 --- a/go-controller/vendor/github.com/stretchr/testify/require/requirements.go +++ b/go-controller/vendor/github.com/stretchr/testify/require/requirements.go @@ -6,7 +6,7 @@ type TestingT interface { FailNow() } -type tHelper interface { +type tHelper = interface { Helper() } diff --git a/go-controller/vendor/go.opentelemetry.io/otel/LICENSE b/go-controller/vendor/go.opentelemetry.io/otel/LICENSE new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/go-controller/vendor/go.opentelemetry.io/otel/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/go-controller/vendor/go.opentelemetry.io/otel/attribute/README.md b/go-controller/vendor/go.opentelemetry.io/otel/attribute/README.md new file mode 100644 index 0000000000..5b3da8f14c --- /dev/null +++ b/go-controller/vendor/go.opentelemetry.io/otel/attribute/README.md @@ -0,0 +1,3 @@ +# Attribute + +[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel/attribute)](https://pkg.go.dev/go.opentelemetry.io/otel/attribute) diff --git a/go-controller/vendor/go.opentelemetry.io/otel/attribute/doc.go b/go-controller/vendor/go.opentelemetry.io/otel/attribute/doc.go new file mode 100644 index 0000000000..eef51ebc2a --- /dev/null +++ b/go-controller/vendor/go.opentelemetry.io/otel/attribute/doc.go @@ -0,0 +1,5 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// Package attribute provides key and value attributes. +package attribute // import "go.opentelemetry.io/otel/attribute" diff --git a/go-controller/vendor/go.opentelemetry.io/otel/attribute/encoder.go b/go-controller/vendor/go.opentelemetry.io/otel/attribute/encoder.go new file mode 100644 index 0000000000..318e42fcab --- /dev/null +++ b/go-controller/vendor/go.opentelemetry.io/otel/attribute/encoder.go @@ -0,0 +1,135 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package attribute // import "go.opentelemetry.io/otel/attribute" + +import ( + "bytes" + "sync" + "sync/atomic" +) + +type ( + // Encoder is a mechanism for serializing an attribute set into a specific + // string representation that supports caching, to avoid repeated + // serialization. An example could be an exporter encoding the attribute + // set into a wire representation. + Encoder interface { + // Encode returns the serialized encoding of the attribute set using + // its Iterator. This result may be cached by a attribute.Set. + Encode(iterator Iterator) string + + // ID returns a value that is unique for each class of attribute + // encoder. Attribute encoders allocate these using `NewEncoderID`. + ID() EncoderID + } + + // EncoderID is used to identify distinct Encoder + // implementations, for caching encoded results. + EncoderID struct { + value uint64 + } + + // defaultAttrEncoder uses a sync.Pool of buffers to reduce the number of + // allocations used in encoding attributes. This implementation encodes a + // comma-separated list of key=value, with '/'-escaping of '=', ',', and + // '\'. + defaultAttrEncoder struct { + // pool is a pool of attribute set builders. The buffers in this pool + // grow to a size that most attribute encodings will not allocate new + // memory. + pool sync.Pool // *bytes.Buffer + } +) + +// escapeChar is used to ensure uniqueness of the attribute encoding where +// keys or values contain either '=' or ','. Since there is no parser needed +// for this encoding and its only requirement is to be unique, this choice is +// arbitrary. Users will see these in some exporters (e.g., stdout), so the +// backslash ('\') is used as a conventional choice. +const escapeChar = '\\' + +var ( + _ Encoder = &defaultAttrEncoder{} + + // encoderIDCounter is for generating IDs for other attribute encoders. + encoderIDCounter uint64 + + defaultEncoderOnce sync.Once + defaultEncoderID = NewEncoderID() + defaultEncoderInstance *defaultAttrEncoder +) + +// NewEncoderID returns a unique attribute encoder ID. It should be called +// once per each type of attribute encoder. Preferably in init() or in var +// definition. +func NewEncoderID() EncoderID { + return EncoderID{value: atomic.AddUint64(&encoderIDCounter, 1)} +} + +// DefaultEncoder returns an attribute encoder that encodes attributes in such +// a way that each escaped attribute's key is followed by an equal sign and +// then by an escaped attribute's value. All key-value pairs are separated by +// a comma. +// +// Escaping is done by prepending a backslash before either a backslash, equal +// sign or a comma. +func DefaultEncoder() Encoder { + defaultEncoderOnce.Do(func() { + defaultEncoderInstance = &defaultAttrEncoder{ + pool: sync.Pool{ + New: func() interface{} { + return &bytes.Buffer{} + }, + }, + } + }) + return defaultEncoderInstance +} + +// Encode is a part of an implementation of the AttributeEncoder interface. +func (d *defaultAttrEncoder) Encode(iter Iterator) string { + buf := d.pool.Get().(*bytes.Buffer) + defer d.pool.Put(buf) + buf.Reset() + + for iter.Next() { + i, keyValue := iter.IndexedAttribute() + if i > 0 { + _, _ = buf.WriteRune(',') + } + copyAndEscape(buf, string(keyValue.Key)) + + _, _ = buf.WriteRune('=') + + if keyValue.Value.Type() == STRING { + copyAndEscape(buf, keyValue.Value.AsString()) + } else { + _, _ = buf.WriteString(keyValue.Value.Emit()) + } + } + return buf.String() +} + +// ID is a part of an implementation of the AttributeEncoder interface. +func (*defaultAttrEncoder) ID() EncoderID { + return defaultEncoderID +} + +// copyAndEscape escapes `=`, `,` and its own escape character (`\`), +// making the default encoding unique. +func copyAndEscape(buf *bytes.Buffer, val string) { + for _, ch := range val { + switch ch { + case '=', ',', escapeChar: + _, _ = buf.WriteRune(escapeChar) + } + _, _ = buf.WriteRune(ch) + } +} + +// Valid returns true if this encoder ID was allocated by +// `NewEncoderID`. Invalid encoder IDs will not be cached. +func (id EncoderID) Valid() bool { + return id.value != 0 +} diff --git a/go-controller/vendor/go.opentelemetry.io/otel/attribute/filter.go b/go-controller/vendor/go.opentelemetry.io/otel/attribute/filter.go new file mode 100644 index 0000000000..be9cd922d8 --- /dev/null +++ b/go-controller/vendor/go.opentelemetry.io/otel/attribute/filter.go @@ -0,0 +1,49 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package attribute // import "go.opentelemetry.io/otel/attribute" + +// Filter supports removing certain attributes from attribute sets. When +// the filter returns true, the attribute will be kept in the filtered +// attribute set. When the filter returns false, the attribute is excluded +// from the filtered attribute set, and the attribute instead appears in +// the removed list of excluded attributes. +type Filter func(KeyValue) bool + +// NewAllowKeysFilter returns a Filter that only allows attributes with one of +// the provided keys. +// +// If keys is empty a deny-all filter is returned. +func NewAllowKeysFilter(keys ...Key) Filter { + if len(keys) <= 0 { + return func(kv KeyValue) bool { return false } + } + + allowed := make(map[Key]struct{}) + for _, k := range keys { + allowed[k] = struct{}{} + } + return func(kv KeyValue) bool { + _, ok := allowed[kv.Key] + return ok + } +} + +// NewDenyKeysFilter returns a Filter that only allows attributes +// that do not have one of the provided keys. +// +// If keys is empty an allow-all filter is returned. +func NewDenyKeysFilter(keys ...Key) Filter { + if len(keys) <= 0 { + return func(kv KeyValue) bool { return true } + } + + forbid := make(map[Key]struct{}) + for _, k := range keys { + forbid[k] = struct{}{} + } + return func(kv KeyValue) bool { + _, ok := forbid[kv.Key] + return !ok + } +} diff --git a/go-controller/vendor/go.opentelemetry.io/otel/attribute/iterator.go b/go-controller/vendor/go.opentelemetry.io/otel/attribute/iterator.go new file mode 100644 index 0000000000..f2ba89ce4b --- /dev/null +++ b/go-controller/vendor/go.opentelemetry.io/otel/attribute/iterator.go @@ -0,0 +1,150 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package attribute // import "go.opentelemetry.io/otel/attribute" + +// Iterator allows iterating over the set of attributes in order, sorted by +// key. +type Iterator struct { + storage *Set + idx int +} + +// MergeIterator supports iterating over two sets of attributes while +// eliminating duplicate values from the combined set. The first iterator +// value takes precedence. +type MergeIterator struct { + one oneIterator + two oneIterator + current KeyValue +} + +type oneIterator struct { + iter Iterator + done bool + attr KeyValue +} + +// Next moves the iterator to the next position. Returns false if there are no +// more attributes. +func (i *Iterator) Next() bool { + i.idx++ + return i.idx < i.Len() +} + +// Label returns current KeyValue. Must be called only after Next returns +// true. +// +// Deprecated: Use Attribute instead. +func (i *Iterator) Label() KeyValue { + return i.Attribute() +} + +// Attribute returns the current KeyValue of the Iterator. It must be called +// only after Next returns true. +func (i *Iterator) Attribute() KeyValue { + kv, _ := i.storage.Get(i.idx) + return kv +} + +// IndexedLabel returns current index and attribute. Must be called only +// after Next returns true. +// +// Deprecated: Use IndexedAttribute instead. +func (i *Iterator) IndexedLabel() (int, KeyValue) { + return i.idx, i.Attribute() +} + +// IndexedAttribute returns current index and attribute. Must be called only +// after Next returns true. +func (i *Iterator) IndexedAttribute() (int, KeyValue) { + return i.idx, i.Attribute() +} + +// Len returns a number of attributes in the iterated set. +func (i *Iterator) Len() int { + return i.storage.Len() +} + +// ToSlice is a convenience function that creates a slice of attributes from +// the passed iterator. The iterator is set up to start from the beginning +// before creating the slice. +func (i *Iterator) ToSlice() []KeyValue { + l := i.Len() + if l == 0 { + return nil + } + i.idx = -1 + slice := make([]KeyValue, 0, l) + for i.Next() { + slice = append(slice, i.Attribute()) + } + return slice +} + +// NewMergeIterator returns a MergeIterator for merging two attribute sets. +// Duplicates are resolved by taking the value from the first set. +func NewMergeIterator(s1, s2 *Set) MergeIterator { + mi := MergeIterator{ + one: makeOne(s1.Iter()), + two: makeOne(s2.Iter()), + } + return mi +} + +func makeOne(iter Iterator) oneIterator { + oi := oneIterator{ + iter: iter, + } + oi.advance() + return oi +} + +func (oi *oneIterator) advance() { + if oi.done = !oi.iter.Next(); !oi.done { + oi.attr = oi.iter.Attribute() + } +} + +// Next returns true if there is another attribute available. +func (m *MergeIterator) Next() bool { + if m.one.done && m.two.done { + return false + } + if m.one.done { + m.current = m.two.attr + m.two.advance() + return true + } + if m.two.done { + m.current = m.one.attr + m.one.advance() + return true + } + if m.one.attr.Key == m.two.attr.Key { + m.current = m.one.attr // first iterator attribute value wins + m.one.advance() + m.two.advance() + return true + } + if m.one.attr.Key < m.two.attr.Key { + m.current = m.one.attr + m.one.advance() + return true + } + m.current = m.two.attr + m.two.advance() + return true +} + +// Label returns the current value after Next() returns true. +// +// Deprecated: Use Attribute instead. +func (m *MergeIterator) Label() KeyValue { + return m.current +} + +// Attribute returns the current value after Next() returns true. +func (m *MergeIterator) Attribute() KeyValue { + return m.current +} diff --git a/go-controller/vendor/go.opentelemetry.io/otel/attribute/key.go b/go-controller/vendor/go.opentelemetry.io/otel/attribute/key.go new file mode 100644 index 0000000000..d9a22c6502 --- /dev/null +++ b/go-controller/vendor/go.opentelemetry.io/otel/attribute/key.go @@ -0,0 +1,123 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package attribute // import "go.opentelemetry.io/otel/attribute" + +// Key represents the key part in key-value pairs. It's a string. The +// allowed character set in the key depends on the use of the key. +type Key string + +// Bool creates a KeyValue instance with a BOOL Value. +// +// If creating both a key and value at the same time, use the provided +// convenience function instead -- Bool(name, value). +func (k Key) Bool(v bool) KeyValue { + return KeyValue{ + Key: k, + Value: BoolValue(v), + } +} + +// BoolSlice creates a KeyValue instance with a BOOLSLICE Value. +// +// If creating both a key and value at the same time, use the provided +// convenience function instead -- BoolSlice(name, value). +func (k Key) BoolSlice(v []bool) KeyValue { + return KeyValue{ + Key: k, + Value: BoolSliceValue(v), + } +} + +// Int creates a KeyValue instance with an INT64 Value. +// +// If creating both a key and value at the same time, use the provided +// convenience function instead -- Int(name, value). +func (k Key) Int(v int) KeyValue { + return KeyValue{ + Key: k, + Value: IntValue(v), + } +} + +// IntSlice creates a KeyValue instance with an INT64SLICE Value. +// +// If creating both a key and value at the same time, use the provided +// convenience function instead -- IntSlice(name, value). +func (k Key) IntSlice(v []int) KeyValue { + return KeyValue{ + Key: k, + Value: IntSliceValue(v), + } +} + +// Int64 creates a KeyValue instance with an INT64 Value. +// +// If creating both a key and value at the same time, use the provided +// convenience function instead -- Int64(name, value). +func (k Key) Int64(v int64) KeyValue { + return KeyValue{ + Key: k, + Value: Int64Value(v), + } +} + +// Int64Slice creates a KeyValue instance with an INT64SLICE Value. +// +// If creating both a key and value at the same time, use the provided +// convenience function instead -- Int64Slice(name, value). +func (k Key) Int64Slice(v []int64) KeyValue { + return KeyValue{ + Key: k, + Value: Int64SliceValue(v), + } +} + +// Float64 creates a KeyValue instance with a FLOAT64 Value. +// +// If creating both a key and value at the same time, use the provided +// convenience function instead -- Float64(name, value). +func (k Key) Float64(v float64) KeyValue { + return KeyValue{ + Key: k, + Value: Float64Value(v), + } +} + +// Float64Slice creates a KeyValue instance with a FLOAT64SLICE Value. +// +// If creating both a key and value at the same time, use the provided +// convenience function instead -- Float64(name, value). +func (k Key) Float64Slice(v []float64) KeyValue { + return KeyValue{ + Key: k, + Value: Float64SliceValue(v), + } +} + +// String creates a KeyValue instance with a STRING Value. +// +// If creating both a key and value at the same time, use the provided +// convenience function instead -- String(name, value). +func (k Key) String(v string) KeyValue { + return KeyValue{ + Key: k, + Value: StringValue(v), + } +} + +// StringSlice creates a KeyValue instance with a STRINGSLICE Value. +// +// If creating both a key and value at the same time, use the provided +// convenience function instead -- StringSlice(name, value). +func (k Key) StringSlice(v []string) KeyValue { + return KeyValue{ + Key: k, + Value: StringSliceValue(v), + } +} + +// Defined returns true for non-empty keys. +func (k Key) Defined() bool { + return len(k) != 0 +} diff --git a/go-controller/vendor/go.opentelemetry.io/otel/attribute/kv.go b/go-controller/vendor/go.opentelemetry.io/otel/attribute/kv.go new file mode 100644 index 0000000000..3028f9a40f --- /dev/null +++ b/go-controller/vendor/go.opentelemetry.io/otel/attribute/kv.go @@ -0,0 +1,75 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package attribute // import "go.opentelemetry.io/otel/attribute" + +import ( + "fmt" +) + +// KeyValue holds a key and value pair. +type KeyValue struct { + Key Key + Value Value +} + +// Valid returns if kv is a valid OpenTelemetry attribute. +func (kv KeyValue) Valid() bool { + return kv.Key.Defined() && kv.Value.Type() != INVALID +} + +// Bool creates a KeyValue with a BOOL Value type. +func Bool(k string, v bool) KeyValue { + return Key(k).Bool(v) +} + +// BoolSlice creates a KeyValue with a BOOLSLICE Value type. +func BoolSlice(k string, v []bool) KeyValue { + return Key(k).BoolSlice(v) +} + +// Int creates a KeyValue with an INT64 Value type. +func Int(k string, v int) KeyValue { + return Key(k).Int(v) +} + +// IntSlice creates a KeyValue with an INT64SLICE Value type. +func IntSlice(k string, v []int) KeyValue { + return Key(k).IntSlice(v) +} + +// Int64 creates a KeyValue with an INT64 Value type. +func Int64(k string, v int64) KeyValue { + return Key(k).Int64(v) +} + +// Int64Slice creates a KeyValue with an INT64SLICE Value type. +func Int64Slice(k string, v []int64) KeyValue { + return Key(k).Int64Slice(v) +} + +// Float64 creates a KeyValue with a FLOAT64 Value type. +func Float64(k string, v float64) KeyValue { + return Key(k).Float64(v) +} + +// Float64Slice creates a KeyValue with a FLOAT64SLICE Value type. +func Float64Slice(k string, v []float64) KeyValue { + return Key(k).Float64Slice(v) +} + +// String creates a KeyValue with a STRING Value type. +func String(k, v string) KeyValue { + return Key(k).String(v) +} + +// StringSlice creates a KeyValue with a STRINGSLICE Value type. +func StringSlice(k string, v []string) KeyValue { + return Key(k).StringSlice(v) +} + +// Stringer creates a new key-value pair with a passed name and a string +// value generated by the passed Stringer interface. +func Stringer(k string, v fmt.Stringer) KeyValue { + return Key(k).String(v.String()) +} diff --git a/go-controller/vendor/go.opentelemetry.io/otel/attribute/set.go b/go-controller/vendor/go.opentelemetry.io/otel/attribute/set.go new file mode 100644 index 0000000000..6cbefceadf --- /dev/null +++ b/go-controller/vendor/go.opentelemetry.io/otel/attribute/set.go @@ -0,0 +1,411 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package attribute // import "go.opentelemetry.io/otel/attribute" + +import ( + "cmp" + "encoding/json" + "reflect" + "slices" + "sort" +) + +type ( + // Set is the representation for a distinct attribute set. It manages an + // immutable set of attributes, with an internal cache for storing + // attribute encodings. + // + // This type will remain comparable for backwards compatibility. The + // equivalence of Sets across versions is not guaranteed to be stable. + // Prior versions may find two Sets to be equal or not when compared + // directly (i.e. ==), but subsequent versions may not. Users should use + // the Equals method to ensure stable equivalence checking. + // + // Users should also use the Distinct returned from Equivalent as a map key + // instead of a Set directly. In addition to that type providing guarantees + // on stable equivalence, it may also provide performance improvements. + Set struct { + equivalent Distinct + } + + // Distinct is a unique identifier of a Set. + // + // Distinct is designed to be ensures equivalence stability: comparisons + // will return the save value across versions. For this reason, Distinct + // should always be used as a map key instead of a Set. + Distinct struct { + iface interface{} + } + + // Sortable implements sort.Interface, used for sorting KeyValue. + // + // Deprecated: This type is no longer used. It was added as a performance + // optimization for Go < 1.21 that is no longer needed (Go < 1.21 is no + // longer supported by the module). + Sortable []KeyValue +) + +var ( + // keyValueType is used in computeDistinctReflect. + keyValueType = reflect.TypeOf(KeyValue{}) + + // emptySet is returned for empty attribute sets. + emptySet = &Set{ + equivalent: Distinct{ + iface: [0]KeyValue{}, + }, + } +) + +// EmptySet returns a reference to a Set with no elements. +// +// This is a convenience provided for optimized calling utility. +func EmptySet() *Set { + return emptySet +} + +// reflectValue abbreviates reflect.ValueOf(d). +func (d Distinct) reflectValue() reflect.Value { + return reflect.ValueOf(d.iface) +} + +// Valid returns true if this value refers to a valid Set. +func (d Distinct) Valid() bool { + return d.iface != nil +} + +// Len returns the number of attributes in this set. +func (l *Set) Len() int { + if l == nil || !l.equivalent.Valid() { + return 0 + } + return l.equivalent.reflectValue().Len() +} + +// Get returns the KeyValue at ordered position idx in this set. +func (l *Set) Get(idx int) (KeyValue, bool) { + if l == nil || !l.equivalent.Valid() { + return KeyValue{}, false + } + value := l.equivalent.reflectValue() + + if idx >= 0 && idx < value.Len() { + // Note: The Go compiler successfully avoids an allocation for + // the interface{} conversion here: + return value.Index(idx).Interface().(KeyValue), true + } + + return KeyValue{}, false +} + +// Value returns the value of a specified key in this set. +func (l *Set) Value(k Key) (Value, bool) { + if l == nil || !l.equivalent.Valid() { + return Value{}, false + } + rValue := l.equivalent.reflectValue() + vlen := rValue.Len() + + idx := sort.Search(vlen, func(idx int) bool { + return rValue.Index(idx).Interface().(KeyValue).Key >= k + }) + if idx >= vlen { + return Value{}, false + } + keyValue := rValue.Index(idx).Interface().(KeyValue) + if k == keyValue.Key { + return keyValue.Value, true + } + return Value{}, false +} + +// HasValue tests whether a key is defined in this set. +func (l *Set) HasValue(k Key) bool { + if l == nil { + return false + } + _, ok := l.Value(k) + return ok +} + +// Iter returns an iterator for visiting the attributes in this set. +func (l *Set) Iter() Iterator { + return Iterator{ + storage: l, + idx: -1, + } +} + +// ToSlice returns the set of attributes belonging to this set, sorted, where +// keys appear no more than once. +func (l *Set) ToSlice() []KeyValue { + iter := l.Iter() + return iter.ToSlice() +} + +// Equivalent returns a value that may be used as a map key. The Distinct type +// guarantees that the result will equal the equivalent. Distinct value of any +// attribute set with the same elements as this, where sets are made unique by +// choosing the last value in the input for any given key. +func (l *Set) Equivalent() Distinct { + if l == nil || !l.equivalent.Valid() { + return emptySet.equivalent + } + return l.equivalent +} + +// Equals returns true if the argument set is equivalent to this set. +func (l *Set) Equals(o *Set) bool { + return l.Equivalent() == o.Equivalent() +} + +// Encoded returns the encoded form of this set, according to encoder. +func (l *Set) Encoded(encoder Encoder) string { + if l == nil || encoder == nil { + return "" + } + + return encoder.Encode(l.Iter()) +} + +func empty() Set { + return Set{ + equivalent: emptySet.equivalent, + } +} + +// NewSet returns a new Set. See the documentation for +// NewSetWithSortableFiltered for more details. +// +// Except for empty sets, this method adds an additional allocation compared +// with calls that include a Sortable. +func NewSet(kvs ...KeyValue) Set { + s, _ := NewSetWithFiltered(kvs, nil) + return s +} + +// NewSetWithSortable returns a new Set. See the documentation for +// NewSetWithSortableFiltered for more details. +// +// This call includes a Sortable option as a memory optimization. +// +// Deprecated: Use [NewSet] instead. +func NewSetWithSortable(kvs []KeyValue, _ *Sortable) Set { + s, _ := NewSetWithFiltered(kvs, nil) + return s +} + +// NewSetWithFiltered returns a new Set. See the documentation for +// NewSetWithSortableFiltered for more details. +// +// This call includes a Filter to include/exclude attribute keys from the +// return value. Excluded keys are returned as a slice of attribute values. +func NewSetWithFiltered(kvs []KeyValue, filter Filter) (Set, []KeyValue) { + // Check for empty set. + if len(kvs) == 0 { + return empty(), nil + } + + // Stable sort so the following de-duplication can implement + // last-value-wins semantics. + slices.SortStableFunc(kvs, func(a, b KeyValue) int { + return cmp.Compare(a.Key, b.Key) + }) + + position := len(kvs) - 1 + offset := position - 1 + + // The requirements stated above require that the stable + // result be placed in the end of the input slice, while + // overwritten values are swapped to the beginning. + // + // De-duplicate with last-value-wins semantics. Preserve + // duplicate values at the beginning of the input slice. + for ; offset >= 0; offset-- { + if kvs[offset].Key == kvs[position].Key { + continue + } + position-- + kvs[offset], kvs[position] = kvs[position], kvs[offset] + } + kvs = kvs[position:] + + if filter != nil { + if div := filteredToFront(kvs, filter); div != 0 { + return Set{equivalent: computeDistinct(kvs[div:])}, kvs[:div] + } + } + return Set{equivalent: computeDistinct(kvs)}, nil +} + +// NewSetWithSortableFiltered returns a new Set. +// +// Duplicate keys are eliminated by taking the last value. This +// re-orders the input slice so that unique last-values are contiguous +// at the end of the slice. +// +// This ensures the following: +// +// - Last-value-wins semantics +// - Caller sees the reordering, but doesn't lose values +// - Repeated call preserve last-value wins. +// +// Note that methods are defined on Set, although this returns Set. Callers +// can avoid memory allocations by: +// +// - allocating a Sortable for use as a temporary in this method +// - allocating a Set for storing the return value of this constructor. +// +// The result maintains a cache of encoded attributes, by attribute.EncoderID. +// This value should not be copied after its first use. +// +// The second []KeyValue return value is a list of attributes that were +// excluded by the Filter (if non-nil). +// +// Deprecated: Use [NewSetWithFiltered] instead. +func NewSetWithSortableFiltered(kvs []KeyValue, _ *Sortable, filter Filter) (Set, []KeyValue) { + return NewSetWithFiltered(kvs, filter) +} + +// filteredToFront filters slice in-place using keep function. All KeyValues that need to +// be removed are moved to the front. All KeyValues that need to be kept are +// moved (in-order) to the back. The index for the first KeyValue to be kept is +// returned. +func filteredToFront(slice []KeyValue, keep Filter) int { + n := len(slice) + j := n + for i := n - 1; i >= 0; i-- { + if keep(slice[i]) { + j-- + slice[i], slice[j] = slice[j], slice[i] + } + } + return j +} + +// Filter returns a filtered copy of this Set. See the documentation for +// NewSetWithSortableFiltered for more details. +func (l *Set) Filter(re Filter) (Set, []KeyValue) { + if re == nil { + return *l, nil + } + + // Iterate in reverse to the first attribute that will be filtered out. + n := l.Len() + first := n - 1 + for ; first >= 0; first-- { + kv, _ := l.Get(first) + if !re(kv) { + break + } + } + + // No attributes will be dropped, return the immutable Set l and nil. + if first < 0 { + return *l, nil + } + + // Copy now that we know we need to return a modified set. + // + // Do not do this in-place on the underlying storage of *Set l. Sets are + // immutable and filtering should not change this. + slice := l.ToSlice() + + // Don't re-iterate the slice if only slice[0] is filtered. + if first == 0 { + // It is safe to assume len(slice) >= 1 given we found at least one + // attribute above that needs to be filtered out. + return Set{equivalent: computeDistinct(slice[1:])}, slice[:1] + } + + // Move the filtered slice[first] to the front (preserving order). + kv := slice[first] + copy(slice[1:first+1], slice[:first]) + slice[0] = kv + + // Do not re-evaluate re(slice[first+1:]). + div := filteredToFront(slice[1:first+1], re) + 1 + return Set{equivalent: computeDistinct(slice[div:])}, slice[:div] +} + +// computeDistinct returns a Distinct using either the fixed- or +// reflect-oriented code path, depending on the size of the input. The input +// slice is assumed to already be sorted and de-duplicated. +func computeDistinct(kvs []KeyValue) Distinct { + iface := computeDistinctFixed(kvs) + if iface == nil { + iface = computeDistinctReflect(kvs) + } + return Distinct{ + iface: iface, + } +} + +// computeDistinctFixed computes a Distinct for small slices. It returns nil +// if the input is too large for this code path. +func computeDistinctFixed(kvs []KeyValue) interface{} { + switch len(kvs) { + case 1: + return [1]KeyValue(kvs) + case 2: + return [2]KeyValue(kvs) + case 3: + return [3]KeyValue(kvs) + case 4: + return [4]KeyValue(kvs) + case 5: + return [5]KeyValue(kvs) + case 6: + return [6]KeyValue(kvs) + case 7: + return [7]KeyValue(kvs) + case 8: + return [8]KeyValue(kvs) + case 9: + return [9]KeyValue(kvs) + case 10: + return [10]KeyValue(kvs) + default: + return nil + } +} + +// computeDistinctReflect computes a Distinct using reflection, works for any +// size input. +func computeDistinctReflect(kvs []KeyValue) interface{} { + at := reflect.New(reflect.ArrayOf(len(kvs), keyValueType)).Elem() + for i, keyValue := range kvs { + *(at.Index(i).Addr().Interface().(*KeyValue)) = keyValue + } + return at.Interface() +} + +// MarshalJSON returns the JSON encoding of the Set. +func (l *Set) MarshalJSON() ([]byte, error) { + return json.Marshal(l.equivalent.iface) +} + +// MarshalLog is the marshaling function used by the logging system to represent this Set. +func (l Set) MarshalLog() interface{} { + kvs := make(map[string]string) + for _, kv := range l.ToSlice() { + kvs[string(kv.Key)] = kv.Value.Emit() + } + return kvs +} + +// Len implements sort.Interface. +func (l *Sortable) Len() int { + return len(*l) +} + +// Swap implements sort.Interface. +func (l *Sortable) Swap(i, j int) { + (*l)[i], (*l)[j] = (*l)[j], (*l)[i] +} + +// Less implements sort.Interface. +func (l *Sortable) Less(i, j int) bool { + return (*l)[i].Key < (*l)[j].Key +} diff --git a/go-controller/vendor/go.opentelemetry.io/otel/attribute/type_string.go b/go-controller/vendor/go.opentelemetry.io/otel/attribute/type_string.go new file mode 100644 index 0000000000..e584b24776 --- /dev/null +++ b/go-controller/vendor/go.opentelemetry.io/otel/attribute/type_string.go @@ -0,0 +1,31 @@ +// Code generated by "stringer -type=Type"; DO NOT EDIT. + +package attribute + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[INVALID-0] + _ = x[BOOL-1] + _ = x[INT64-2] + _ = x[FLOAT64-3] + _ = x[STRING-4] + _ = x[BOOLSLICE-5] + _ = x[INT64SLICE-6] + _ = x[FLOAT64SLICE-7] + _ = x[STRINGSLICE-8] +} + +const _Type_name = "INVALIDBOOLINT64FLOAT64STRINGBOOLSLICEINT64SLICEFLOAT64SLICESTRINGSLICE" + +var _Type_index = [...]uint8{0, 7, 11, 16, 23, 29, 38, 48, 60, 71} + +func (i Type) String() string { + if i < 0 || i >= Type(len(_Type_index)-1) { + return "Type(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _Type_name[_Type_index[i]:_Type_index[i+1]] +} diff --git a/go-controller/vendor/go.opentelemetry.io/otel/attribute/value.go b/go-controller/vendor/go.opentelemetry.io/otel/attribute/value.go new file mode 100644 index 0000000000..9ea0ecbbd2 --- /dev/null +++ b/go-controller/vendor/go.opentelemetry.io/otel/attribute/value.go @@ -0,0 +1,271 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package attribute // import "go.opentelemetry.io/otel/attribute" + +import ( + "encoding/json" + "fmt" + "reflect" + "strconv" + + "go.opentelemetry.io/otel/internal" + "go.opentelemetry.io/otel/internal/attribute" +) + +//go:generate stringer -type=Type + +// Type describes the type of the data Value holds. +type Type int // nolint: revive // redefines builtin Type. + +// Value represents the value part in key-value pairs. +type Value struct { + vtype Type + numeric uint64 + stringly string + slice interface{} +} + +const ( + // INVALID is used for a Value with no value set. + INVALID Type = iota + // BOOL is a boolean Type Value. + BOOL + // INT64 is a 64-bit signed integral Type Value. + INT64 + // FLOAT64 is a 64-bit floating point Type Value. + FLOAT64 + // STRING is a string Type Value. + STRING + // BOOLSLICE is a slice of booleans Type Value. + BOOLSLICE + // INT64SLICE is a slice of 64-bit signed integral numbers Type Value. + INT64SLICE + // FLOAT64SLICE is a slice of 64-bit floating point numbers Type Value. + FLOAT64SLICE + // STRINGSLICE is a slice of strings Type Value. + STRINGSLICE +) + +// BoolValue creates a BOOL Value. +func BoolValue(v bool) Value { + return Value{ + vtype: BOOL, + numeric: internal.BoolToRaw(v), + } +} + +// BoolSliceValue creates a BOOLSLICE Value. +func BoolSliceValue(v []bool) Value { + return Value{vtype: BOOLSLICE, slice: attribute.BoolSliceValue(v)} +} + +// IntValue creates an INT64 Value. +func IntValue(v int) Value { + return Int64Value(int64(v)) +} + +// IntSliceValue creates an INTSLICE Value. +func IntSliceValue(v []int) Value { + var int64Val int64 + cp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeOf(int64Val))) + for i, val := range v { + cp.Elem().Index(i).SetInt(int64(val)) + } + return Value{ + vtype: INT64SLICE, + slice: cp.Elem().Interface(), + } +} + +// Int64Value creates an INT64 Value. +func Int64Value(v int64) Value { + return Value{ + vtype: INT64, + numeric: internal.Int64ToRaw(v), + } +} + +// Int64SliceValue creates an INT64SLICE Value. +func Int64SliceValue(v []int64) Value { + return Value{vtype: INT64SLICE, slice: attribute.Int64SliceValue(v)} +} + +// Float64Value creates a FLOAT64 Value. +func Float64Value(v float64) Value { + return Value{ + vtype: FLOAT64, + numeric: internal.Float64ToRaw(v), + } +} + +// Float64SliceValue creates a FLOAT64SLICE Value. +func Float64SliceValue(v []float64) Value { + return Value{vtype: FLOAT64SLICE, slice: attribute.Float64SliceValue(v)} +} + +// StringValue creates a STRING Value. +func StringValue(v string) Value { + return Value{ + vtype: STRING, + stringly: v, + } +} + +// StringSliceValue creates a STRINGSLICE Value. +func StringSliceValue(v []string) Value { + return Value{vtype: STRINGSLICE, slice: attribute.StringSliceValue(v)} +} + +// Type returns a type of the Value. +func (v Value) Type() Type { + return v.vtype +} + +// AsBool returns the bool value. Make sure that the Value's type is +// BOOL. +func (v Value) AsBool() bool { + return internal.RawToBool(v.numeric) +} + +// AsBoolSlice returns the []bool value. Make sure that the Value's type is +// BOOLSLICE. +func (v Value) AsBoolSlice() []bool { + if v.vtype != BOOLSLICE { + return nil + } + return v.asBoolSlice() +} + +func (v Value) asBoolSlice() []bool { + return attribute.AsBoolSlice(v.slice) +} + +// AsInt64 returns the int64 value. Make sure that the Value's type is +// INT64. +func (v Value) AsInt64() int64 { + return internal.RawToInt64(v.numeric) +} + +// AsInt64Slice returns the []int64 value. Make sure that the Value's type is +// INT64SLICE. +func (v Value) AsInt64Slice() []int64 { + if v.vtype != INT64SLICE { + return nil + } + return v.asInt64Slice() +} + +func (v Value) asInt64Slice() []int64 { + return attribute.AsInt64Slice(v.slice) +} + +// AsFloat64 returns the float64 value. Make sure that the Value's +// type is FLOAT64. +func (v Value) AsFloat64() float64 { + return internal.RawToFloat64(v.numeric) +} + +// AsFloat64Slice returns the []float64 value. Make sure that the Value's type is +// FLOAT64SLICE. +func (v Value) AsFloat64Slice() []float64 { + if v.vtype != FLOAT64SLICE { + return nil + } + return v.asFloat64Slice() +} + +func (v Value) asFloat64Slice() []float64 { + return attribute.AsFloat64Slice(v.slice) +} + +// AsString returns the string value. Make sure that the Value's type +// is STRING. +func (v Value) AsString() string { + return v.stringly +} + +// AsStringSlice returns the []string value. Make sure that the Value's type is +// STRINGSLICE. +func (v Value) AsStringSlice() []string { + if v.vtype != STRINGSLICE { + return nil + } + return v.asStringSlice() +} + +func (v Value) asStringSlice() []string { + return attribute.AsStringSlice(v.slice) +} + +type unknownValueType struct{} + +// AsInterface returns Value's data as interface{}. +func (v Value) AsInterface() interface{} { + switch v.Type() { + case BOOL: + return v.AsBool() + case BOOLSLICE: + return v.asBoolSlice() + case INT64: + return v.AsInt64() + case INT64SLICE: + return v.asInt64Slice() + case FLOAT64: + return v.AsFloat64() + case FLOAT64SLICE: + return v.asFloat64Slice() + case STRING: + return v.stringly + case STRINGSLICE: + return v.asStringSlice() + } + return unknownValueType{} +} + +// Emit returns a string representation of Value's data. +func (v Value) Emit() string { + switch v.Type() { + case BOOLSLICE: + return fmt.Sprint(v.asBoolSlice()) + case BOOL: + return strconv.FormatBool(v.AsBool()) + case INT64SLICE: + j, err := json.Marshal(v.asInt64Slice()) + if err != nil { + return fmt.Sprintf("invalid: %v", v.asInt64Slice()) + } + return string(j) + case INT64: + return strconv.FormatInt(v.AsInt64(), 10) + case FLOAT64SLICE: + j, err := json.Marshal(v.asFloat64Slice()) + if err != nil { + return fmt.Sprintf("invalid: %v", v.asFloat64Slice()) + } + return string(j) + case FLOAT64: + return fmt.Sprint(v.AsFloat64()) + case STRINGSLICE: + j, err := json.Marshal(v.asStringSlice()) + if err != nil { + return fmt.Sprintf("invalid: %v", v.asStringSlice()) + } + return string(j) + case STRING: + return v.stringly + default: + return "unknown" + } +} + +// MarshalJSON returns the JSON encoding of the Value. +func (v Value) MarshalJSON() ([]byte, error) { + var jsonVal struct { + Type string + Value interface{} + } + jsonVal.Type = v.Type().String() + jsonVal.Value = v.AsInterface() + return json.Marshal(jsonVal) +} diff --git a/go-controller/vendor/go.opentelemetry.io/otel/codes/README.md b/go-controller/vendor/go.opentelemetry.io/otel/codes/README.md new file mode 100644 index 0000000000..24c52b387d --- /dev/null +++ b/go-controller/vendor/go.opentelemetry.io/otel/codes/README.md @@ -0,0 +1,3 @@ +# Codes + +[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel/codes)](https://pkg.go.dev/go.opentelemetry.io/otel/codes) diff --git a/go-controller/vendor/go.opentelemetry.io/otel/codes/codes.go b/go-controller/vendor/go.opentelemetry.io/otel/codes/codes.go new file mode 100644 index 0000000000..49a35b1225 --- /dev/null +++ b/go-controller/vendor/go.opentelemetry.io/otel/codes/codes.go @@ -0,0 +1,106 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package codes // import "go.opentelemetry.io/otel/codes" + +import ( + "encoding/json" + "errors" + "fmt" + "strconv" +) + +const ( + // Unset is the default status code. + Unset Code = 0 + + // Error indicates the operation contains an error. + // + // NOTE: The error code in OTLP is 2. + // The value of this enum is only relevant to the internals + // of the Go SDK. + Error Code = 1 + + // Ok indicates operation has been validated by an Application developers + // or Operator to have completed successfully, or contain no error. + // + // NOTE: The Ok code in OTLP is 1. + // The value of this enum is only relevant to the internals + // of the Go SDK. + Ok Code = 2 + + maxCode = 3 +) + +// Code is an 32-bit representation of a status state. +type Code uint32 + +var codeToStr = map[Code]string{ + Unset: "Unset", + Error: "Error", + Ok: "Ok", +} + +var strToCode = map[string]Code{ + `"Unset"`: Unset, + `"Error"`: Error, + `"Ok"`: Ok, +} + +// String returns the Code as a string. +func (c Code) String() string { + return codeToStr[c] +} + +// UnmarshalJSON unmarshals b into the Code. +// +// This is based on the functionality in the gRPC codes package: +// https://github.com/grpc/grpc-go/blob/bb64fee312b46ebee26be43364a7a966033521b1/codes/codes.go#L218-L244 +func (c *Code) UnmarshalJSON(b []byte) error { + // From json.Unmarshaler: By convention, to approximate the behavior of + // Unmarshal itself, Unmarshalers implement UnmarshalJSON([]byte("null")) as + // a no-op. + if string(b) == "null" { + return nil + } + if c == nil { + return errors.New("nil receiver passed to UnmarshalJSON") + } + + var x interface{} + if err := json.Unmarshal(b, &x); err != nil { + return err + } + switch x.(type) { + case string: + if jc, ok := strToCode[string(b)]; ok { + *c = jc + return nil + } + return fmt.Errorf("invalid code: %q", string(b)) + case float64: + if ci, err := strconv.ParseUint(string(b), 10, 32); err == nil { + if ci >= maxCode { + return fmt.Errorf("invalid code: %q", ci) + } + + *c = Code(ci) // nolint: gosec // Bit size of 32 check above. + return nil + } + return fmt.Errorf("invalid code: %q", string(b)) + default: + return fmt.Errorf("invalid code: %q", string(b)) + } +} + +// MarshalJSON returns c as the JSON encoding of c. +func (c *Code) MarshalJSON() ([]byte, error) { + if c == nil { + return []byte("null"), nil + } + str, ok := codeToStr[*c] + if !ok { + return nil, fmt.Errorf("invalid code: %d", *c) + } + return []byte(fmt.Sprintf("%q", str)), nil +} diff --git a/go-controller/vendor/go.opentelemetry.io/otel/codes/doc.go b/go-controller/vendor/go.opentelemetry.io/otel/codes/doc.go new file mode 100644 index 0000000000..ee8db448b8 --- /dev/null +++ b/go-controller/vendor/go.opentelemetry.io/otel/codes/doc.go @@ -0,0 +1,10 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +/* +Package codes defines the canonical error codes used by OpenTelemetry. + +It conforms to [the OpenTelemetry +specification](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/trace/api.md#set-status). +*/ +package codes // import "go.opentelemetry.io/otel/codes" diff --git a/go-controller/vendor/go.opentelemetry.io/otel/internal/attribute/attribute.go b/go-controller/vendor/go.opentelemetry.io/otel/internal/attribute/attribute.go new file mode 100644 index 0000000000..691d96c755 --- /dev/null +++ b/go-controller/vendor/go.opentelemetry.io/otel/internal/attribute/attribute.go @@ -0,0 +1,96 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +/* +Package attribute provide several helper functions for some commonly used +logic of processing attributes. +*/ +package attribute // import "go.opentelemetry.io/otel/internal/attribute" + +import ( + "reflect" +) + +// BoolSliceValue converts a bool slice into an array with same elements as slice. +func BoolSliceValue(v []bool) interface{} { + var zero bool + cp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeOf(zero))).Elem() + reflect.Copy(cp, reflect.ValueOf(v)) + return cp.Interface() +} + +// Int64SliceValue converts an int64 slice into an array with same elements as slice. +func Int64SliceValue(v []int64) interface{} { + var zero int64 + cp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeOf(zero))).Elem() + reflect.Copy(cp, reflect.ValueOf(v)) + return cp.Interface() +} + +// Float64SliceValue converts a float64 slice into an array with same elements as slice. +func Float64SliceValue(v []float64) interface{} { + var zero float64 + cp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeOf(zero))).Elem() + reflect.Copy(cp, reflect.ValueOf(v)) + return cp.Interface() +} + +// StringSliceValue converts a string slice into an array with same elements as slice. +func StringSliceValue(v []string) interface{} { + var zero string + cp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeOf(zero))).Elem() + reflect.Copy(cp, reflect.ValueOf(v)) + return cp.Interface() +} + +// AsBoolSlice converts a bool array into a slice into with same elements as array. +func AsBoolSlice(v interface{}) []bool { + rv := reflect.ValueOf(v) + if rv.Type().Kind() != reflect.Array { + return nil + } + cpy := make([]bool, rv.Len()) + if len(cpy) > 0 { + _ = reflect.Copy(reflect.ValueOf(cpy), rv) + } + return cpy +} + +// AsInt64Slice converts an int64 array into a slice into with same elements as array. +func AsInt64Slice(v interface{}) []int64 { + rv := reflect.ValueOf(v) + if rv.Type().Kind() != reflect.Array { + return nil + } + cpy := make([]int64, rv.Len()) + if len(cpy) > 0 { + _ = reflect.Copy(reflect.ValueOf(cpy), rv) + } + return cpy +} + +// AsFloat64Slice converts a float64 array into a slice into with same elements as array. +func AsFloat64Slice(v interface{}) []float64 { + rv := reflect.ValueOf(v) + if rv.Type().Kind() != reflect.Array { + return nil + } + cpy := make([]float64, rv.Len()) + if len(cpy) > 0 { + _ = reflect.Copy(reflect.ValueOf(cpy), rv) + } + return cpy +} + +// AsStringSlice converts a string array into a slice into with same elements as array. +func AsStringSlice(v interface{}) []string { + rv := reflect.ValueOf(v) + if rv.Type().Kind() != reflect.Array { + return nil + } + cpy := make([]string, rv.Len()) + if len(cpy) > 0 { + _ = reflect.Copy(reflect.ValueOf(cpy), rv) + } + return cpy +} diff --git a/go-controller/vendor/go.opentelemetry.io/otel/internal/gen.go b/go-controller/vendor/go.opentelemetry.io/otel/internal/gen.go new file mode 100644 index 0000000000..4259f0320d --- /dev/null +++ b/go-controller/vendor/go.opentelemetry.io/otel/internal/gen.go @@ -0,0 +1,18 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package internal // import "go.opentelemetry.io/otel/internal" + +//go:generate gotmpl --body=./shared/matchers/expectation.go.tmpl "--data={}" --out=matchers/expectation.go +//go:generate gotmpl --body=./shared/matchers/expecter.go.tmpl "--data={}" --out=matchers/expecter.go +//go:generate gotmpl --body=./shared/matchers/temporal_matcher.go.tmpl "--data={}" --out=matchers/temporal_matcher.go + +//go:generate gotmpl --body=./shared/internaltest/alignment.go.tmpl "--data={}" --out=internaltest/alignment.go +//go:generate gotmpl --body=./shared/internaltest/env.go.tmpl "--data={}" --out=internaltest/env.go +//go:generate gotmpl --body=./shared/internaltest/env_test.go.tmpl "--data={}" --out=internaltest/env_test.go +//go:generate gotmpl --body=./shared/internaltest/errors.go.tmpl "--data={}" --out=internaltest/errors.go +//go:generate gotmpl --body=./shared/internaltest/harness.go.tmpl "--data={\"matchersImportPath\": \"go.opentelemetry.io/otel/internal/matchers\"}" --out=internaltest/harness.go +//go:generate gotmpl --body=./shared/internaltest/text_map_carrier.go.tmpl "--data={}" --out=internaltest/text_map_carrier.go +//go:generate gotmpl --body=./shared/internaltest/text_map_carrier_test.go.tmpl "--data={}" --out=internaltest/text_map_carrier_test.go +//go:generate gotmpl --body=./shared/internaltest/text_map_propagator.go.tmpl "--data={}" --out=internaltest/text_map_propagator.go +//go:generate gotmpl --body=./shared/internaltest/text_map_propagator_test.go.tmpl "--data={}" --out=internaltest/text_map_propagator_test.go diff --git a/go-controller/vendor/go.opentelemetry.io/otel/internal/rawhelpers.go b/go-controller/vendor/go.opentelemetry.io/otel/internal/rawhelpers.go new file mode 100644 index 0000000000..b2fe3e41d3 --- /dev/null +++ b/go-controller/vendor/go.opentelemetry.io/otel/internal/rawhelpers.go @@ -0,0 +1,48 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package internal // import "go.opentelemetry.io/otel/internal" + +import ( + "math" + "unsafe" +) + +func BoolToRaw(b bool) uint64 { // nolint:revive // b is not a control flag. + if b { + return 1 + } + return 0 +} + +func RawToBool(r uint64) bool { + return r != 0 +} + +func Int64ToRaw(i int64) uint64 { + // Assumes original was a valid int64 (overflow not checked). + return uint64(i) // nolint: gosec +} + +func RawToInt64(r uint64) int64 { + // Assumes original was a valid int64 (overflow not checked). + return int64(r) // nolint: gosec +} + +func Float64ToRaw(f float64) uint64 { + return math.Float64bits(f) +} + +func RawToFloat64(r uint64) float64 { + return math.Float64frombits(r) +} + +func RawPtrToFloat64Ptr(r *uint64) *float64 { + // Assumes original was a valid *float64 (overflow not checked). + return (*float64)(unsafe.Pointer(r)) // nolint: gosec +} + +func RawPtrToInt64Ptr(r *uint64) *int64 { + // Assumes original was a valid *int64 (overflow not checked). + return (*int64)(unsafe.Pointer(r)) // nolint: gosec +} diff --git a/go-controller/vendor/go.opentelemetry.io/otel/trace/LICENSE b/go-controller/vendor/go.opentelemetry.io/otel/trace/LICENSE new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/go-controller/vendor/go.opentelemetry.io/otel/trace/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/go-controller/vendor/go.opentelemetry.io/otel/trace/README.md b/go-controller/vendor/go.opentelemetry.io/otel/trace/README.md new file mode 100644 index 0000000000..58ccaba69b --- /dev/null +++ b/go-controller/vendor/go.opentelemetry.io/otel/trace/README.md @@ -0,0 +1,3 @@ +# Trace API + +[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel/trace)](https://pkg.go.dev/go.opentelemetry.io/otel/trace) diff --git a/go-controller/vendor/go.opentelemetry.io/otel/trace/config.go b/go-controller/vendor/go.opentelemetry.io/otel/trace/config.go new file mode 100644 index 0000000000..9c0b720a4d --- /dev/null +++ b/go-controller/vendor/go.opentelemetry.io/otel/trace/config.go @@ -0,0 +1,323 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package trace // import "go.opentelemetry.io/otel/trace" + +import ( + "time" + + "go.opentelemetry.io/otel/attribute" +) + +// TracerConfig is a group of options for a Tracer. +type TracerConfig struct { + instrumentationVersion string + // Schema URL of the telemetry emitted by the Tracer. + schemaURL string + attrs attribute.Set +} + +// InstrumentationVersion returns the version of the library providing instrumentation. +func (t *TracerConfig) InstrumentationVersion() string { + return t.instrumentationVersion +} + +// InstrumentationAttributes returns the attributes associated with the library +// providing instrumentation. +func (t *TracerConfig) InstrumentationAttributes() attribute.Set { + return t.attrs +} + +// SchemaURL returns the Schema URL of the telemetry emitted by the Tracer. +func (t *TracerConfig) SchemaURL() string { + return t.schemaURL +} + +// NewTracerConfig applies all the options to a returned TracerConfig. +func NewTracerConfig(options ...TracerOption) TracerConfig { + var config TracerConfig + for _, option := range options { + config = option.apply(config) + } + return config +} + +// TracerOption applies an option to a TracerConfig. +type TracerOption interface { + apply(TracerConfig) TracerConfig +} + +type tracerOptionFunc func(TracerConfig) TracerConfig + +func (fn tracerOptionFunc) apply(cfg TracerConfig) TracerConfig { + return fn(cfg) +} + +// SpanConfig is a group of options for a Span. +type SpanConfig struct { + attributes []attribute.KeyValue + timestamp time.Time + links []Link + newRoot bool + spanKind SpanKind + stackTrace bool +} + +// Attributes describe the associated qualities of a Span. +func (cfg *SpanConfig) Attributes() []attribute.KeyValue { + return cfg.attributes +} + +// Timestamp is a time in a Span life-cycle. +func (cfg *SpanConfig) Timestamp() time.Time { + return cfg.timestamp +} + +// StackTrace checks whether stack trace capturing is enabled. +func (cfg *SpanConfig) StackTrace() bool { + return cfg.stackTrace +} + +// Links are the associations a Span has with other Spans. +func (cfg *SpanConfig) Links() []Link { + return cfg.links +} + +// NewRoot identifies a Span as the root Span for a new trace. This is +// commonly used when an existing trace crosses trust boundaries and the +// remote parent span context should be ignored for security. +func (cfg *SpanConfig) NewRoot() bool { + return cfg.newRoot +} + +// SpanKind is the role a Span has in a trace. +func (cfg *SpanConfig) SpanKind() SpanKind { + return cfg.spanKind +} + +// NewSpanStartConfig applies all the options to a returned SpanConfig. +// No validation is performed on the returned SpanConfig (e.g. no uniqueness +// checking or bounding of data), it is left to the SDK to perform this +// action. +func NewSpanStartConfig(options ...SpanStartOption) SpanConfig { + var c SpanConfig + for _, option := range options { + c = option.applySpanStart(c) + } + return c +} + +// NewSpanEndConfig applies all the options to a returned SpanConfig. +// No validation is performed on the returned SpanConfig (e.g. no uniqueness +// checking or bounding of data), it is left to the SDK to perform this +// action. +func NewSpanEndConfig(options ...SpanEndOption) SpanConfig { + var c SpanConfig + for _, option := range options { + c = option.applySpanEnd(c) + } + return c +} + +// SpanStartOption applies an option to a SpanConfig. These options are applicable +// only when the span is created. +type SpanStartOption interface { + applySpanStart(SpanConfig) SpanConfig +} + +type spanOptionFunc func(SpanConfig) SpanConfig + +func (fn spanOptionFunc) applySpanStart(cfg SpanConfig) SpanConfig { + return fn(cfg) +} + +// SpanEndOption applies an option to a SpanConfig. These options are +// applicable only when the span is ended. +type SpanEndOption interface { + applySpanEnd(SpanConfig) SpanConfig +} + +// EventConfig is a group of options for an Event. +type EventConfig struct { + attributes []attribute.KeyValue + timestamp time.Time + stackTrace bool +} + +// Attributes describe the associated qualities of an Event. +func (cfg *EventConfig) Attributes() []attribute.KeyValue { + return cfg.attributes +} + +// Timestamp is a time in an Event life-cycle. +func (cfg *EventConfig) Timestamp() time.Time { + return cfg.timestamp +} + +// StackTrace checks whether stack trace capturing is enabled. +func (cfg *EventConfig) StackTrace() bool { + return cfg.stackTrace +} + +// NewEventConfig applies all the EventOptions to a returned EventConfig. If no +// timestamp option is passed, the returned EventConfig will have a Timestamp +// set to the call time, otherwise no validation is performed on the returned +// EventConfig. +func NewEventConfig(options ...EventOption) EventConfig { + var c EventConfig + for _, option := range options { + c = option.applyEvent(c) + } + if c.timestamp.IsZero() { + c.timestamp = time.Now() + } + return c +} + +// EventOption applies span event options to an EventConfig. +type EventOption interface { + applyEvent(EventConfig) EventConfig +} + +// SpanOption are options that can be used at both the beginning and end of a span. +type SpanOption interface { + SpanStartOption + SpanEndOption +} + +// SpanStartEventOption are options that can be used at the start of a span, or with an event. +type SpanStartEventOption interface { + SpanStartOption + EventOption +} + +// SpanEndEventOption are options that can be used at the end of a span, or with an event. +type SpanEndEventOption interface { + SpanEndOption + EventOption +} + +type attributeOption []attribute.KeyValue + +func (o attributeOption) applySpan(c SpanConfig) SpanConfig { + c.attributes = append(c.attributes, []attribute.KeyValue(o)...) + return c +} +func (o attributeOption) applySpanStart(c SpanConfig) SpanConfig { return o.applySpan(c) } +func (o attributeOption) applyEvent(c EventConfig) EventConfig { + c.attributes = append(c.attributes, []attribute.KeyValue(o)...) + return c +} + +var _ SpanStartEventOption = attributeOption{} + +// WithAttributes adds the attributes related to a span life-cycle event. +// These attributes are used to describe the work a Span represents when this +// option is provided to a Span's start event. Otherwise, these +// attributes provide additional information about the event being recorded +// (e.g. error, state change, processing progress, system event). +// +// If multiple of these options are passed the attributes of each successive +// option will extend the attributes instead of overwriting. There is no +// guarantee of uniqueness in the resulting attributes. +func WithAttributes(attributes ...attribute.KeyValue) SpanStartEventOption { + return attributeOption(attributes) +} + +// SpanEventOption are options that can be used with an event or a span. +type SpanEventOption interface { + SpanOption + EventOption +} + +type timestampOption time.Time + +func (o timestampOption) applySpan(c SpanConfig) SpanConfig { + c.timestamp = time.Time(o) + return c +} +func (o timestampOption) applySpanStart(c SpanConfig) SpanConfig { return o.applySpan(c) } +func (o timestampOption) applySpanEnd(c SpanConfig) SpanConfig { return o.applySpan(c) } +func (o timestampOption) applyEvent(c EventConfig) EventConfig { + c.timestamp = time.Time(o) + return c +} + +var _ SpanEventOption = timestampOption{} + +// WithTimestamp sets the time of a Span or Event life-cycle moment (e.g. +// started, stopped, errored). +func WithTimestamp(t time.Time) SpanEventOption { + return timestampOption(t) +} + +type stackTraceOption bool + +func (o stackTraceOption) applyEvent(c EventConfig) EventConfig { + c.stackTrace = bool(o) + return c +} + +func (o stackTraceOption) applySpan(c SpanConfig) SpanConfig { + c.stackTrace = bool(o) + return c +} +func (o stackTraceOption) applySpanEnd(c SpanConfig) SpanConfig { return o.applySpan(c) } + +// WithStackTrace sets the flag to capture the error with stack trace (e.g. true, false). +func WithStackTrace(b bool) SpanEndEventOption { + return stackTraceOption(b) +} + +// WithLinks adds links to a Span. The links are added to the existing Span +// links, i.e. this does not overwrite. Links with invalid span context are ignored. +func WithLinks(links ...Link) SpanStartOption { + return spanOptionFunc(func(cfg SpanConfig) SpanConfig { + cfg.links = append(cfg.links, links...) + return cfg + }) +} + +// WithNewRoot specifies that the Span should be treated as a root Span. Any +// existing parent span context will be ignored when defining the Span's trace +// identifiers. +func WithNewRoot() SpanStartOption { + return spanOptionFunc(func(cfg SpanConfig) SpanConfig { + cfg.newRoot = true + return cfg + }) +} + +// WithSpanKind sets the SpanKind of a Span. +func WithSpanKind(kind SpanKind) SpanStartOption { + return spanOptionFunc(func(cfg SpanConfig) SpanConfig { + cfg.spanKind = kind + return cfg + }) +} + +// WithInstrumentationVersion sets the instrumentation version. +func WithInstrumentationVersion(version string) TracerOption { + return tracerOptionFunc(func(cfg TracerConfig) TracerConfig { + cfg.instrumentationVersion = version + return cfg + }) +} + +// WithInstrumentationAttributes sets the instrumentation attributes. +// +// The passed attributes will be de-duplicated. +func WithInstrumentationAttributes(attr ...attribute.KeyValue) TracerOption { + return tracerOptionFunc(func(config TracerConfig) TracerConfig { + config.attrs = attribute.NewSet(attr...) + return config + }) +} + +// WithSchemaURL sets the schema URL for the Tracer. +func WithSchemaURL(schemaURL string) TracerOption { + return tracerOptionFunc(func(cfg TracerConfig) TracerConfig { + cfg.schemaURL = schemaURL + return cfg + }) +} diff --git a/go-controller/vendor/go.opentelemetry.io/otel/trace/context.go b/go-controller/vendor/go.opentelemetry.io/otel/trace/context.go new file mode 100644 index 0000000000..8c45a7107f --- /dev/null +++ b/go-controller/vendor/go.opentelemetry.io/otel/trace/context.go @@ -0,0 +1,50 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package trace // import "go.opentelemetry.io/otel/trace" + +import "context" + +type traceContextKeyType int + +const currentSpanKey traceContextKeyType = iota + +// ContextWithSpan returns a copy of parent with span set as the current Span. +func ContextWithSpan(parent context.Context, span Span) context.Context { + return context.WithValue(parent, currentSpanKey, span) +} + +// ContextWithSpanContext returns a copy of parent with sc as the current +// Span. The Span implementation that wraps sc is non-recording and performs +// no operations other than to return sc as the SpanContext from the +// SpanContext method. +func ContextWithSpanContext(parent context.Context, sc SpanContext) context.Context { + return ContextWithSpan(parent, nonRecordingSpan{sc: sc}) +} + +// ContextWithRemoteSpanContext returns a copy of parent with rsc set explicitly +// as a remote SpanContext and as the current Span. The Span implementation +// that wraps rsc is non-recording and performs no operations other than to +// return rsc as the SpanContext from the SpanContext method. +func ContextWithRemoteSpanContext(parent context.Context, rsc SpanContext) context.Context { + return ContextWithSpanContext(parent, rsc.WithRemote(true)) +} + +// SpanFromContext returns the current Span from ctx. +// +// If no Span is currently set in ctx an implementation of a Span that +// performs no operations is returned. +func SpanFromContext(ctx context.Context) Span { + if ctx == nil { + return noopSpanInstance + } + if span, ok := ctx.Value(currentSpanKey).(Span); ok { + return span + } + return noopSpanInstance +} + +// SpanContextFromContext returns the current Span's SpanContext. +func SpanContextFromContext(ctx context.Context) SpanContext { + return SpanFromContext(ctx).SpanContext() +} diff --git a/go-controller/vendor/go.opentelemetry.io/otel/trace/doc.go b/go-controller/vendor/go.opentelemetry.io/otel/trace/doc.go new file mode 100644 index 0000000000..cdbf41d6d7 --- /dev/null +++ b/go-controller/vendor/go.opentelemetry.io/otel/trace/doc.go @@ -0,0 +1,119 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +/* +Package trace provides an implementation of the tracing part of the +OpenTelemetry API. + +To participate in distributed traces a Span needs to be created for the +operation being performed as part of a traced workflow. In its simplest form: + + var tracer trace.Tracer + + func init() { + tracer = otel.Tracer("instrumentation/package/name") + } + + func operation(ctx context.Context) { + var span trace.Span + ctx, span = tracer.Start(ctx, "operation") + defer span.End() + // ... + } + +A Tracer is unique to the instrumentation and is used to create Spans. +Instrumentation should be designed to accept a TracerProvider from which it +can create its own unique Tracer. Alternatively, the registered global +TracerProvider from the go.opentelemetry.io/otel package can be used as +a default. + + const ( + name = "instrumentation/package/name" + version = "0.1.0" + ) + + type Instrumentation struct { + tracer trace.Tracer + } + + func NewInstrumentation(tp trace.TracerProvider) *Instrumentation { + if tp == nil { + tp = otel.TracerProvider() + } + return &Instrumentation{ + tracer: tp.Tracer(name, trace.WithInstrumentationVersion(version)), + } + } + + func operation(ctx context.Context, inst *Instrumentation) { + var span trace.Span + ctx, span = inst.tracer.Start(ctx, "operation") + defer span.End() + // ... + } + +# API Implementations + +This package does not conform to the standard Go versioning policy; all of its +interfaces may have methods added to them without a package major version bump. +This non-standard API evolution could surprise an uninformed implementation +author. They could unknowingly build their implementation in a way that would +result in a runtime panic for their users that update to the new API. + +The API is designed to help inform an instrumentation author about this +non-standard API evolution. It requires them to choose a default behavior for +unimplemented interface methods. There are three behavior choices they can +make: + + - Compilation failure + - Panic + - Default to another implementation + +All interfaces in this API embed a corresponding interface from +[go.opentelemetry.io/otel/trace/embedded]. If an author wants the default +behavior of their implementations to be a compilation failure, signaling to +their users they need to update to the latest version of that implementation, +they need to embed the corresponding interface from +[go.opentelemetry.io/otel/trace/embedded] in their implementation. For +example, + + import "go.opentelemetry.io/otel/trace/embedded" + + type TracerProvider struct { + embedded.TracerProvider + // ... + } + +If an author wants the default behavior of their implementations to panic, they +can embed the API interface directly. + + import "go.opentelemetry.io/otel/trace" + + type TracerProvider struct { + trace.TracerProvider + // ... + } + +This option is not recommended. It will lead to publishing packages that +contain runtime panics when users update to newer versions of +[go.opentelemetry.io/otel/trace], which may be done with a transitive +dependency. + +Finally, an author can embed another implementation in theirs. The embedded +implementation will be used for methods not defined by the author. For example, +an author who wants to default to silently dropping the call can use +[go.opentelemetry.io/otel/trace/noop]: + + import "go.opentelemetry.io/otel/trace/noop" + + type TracerProvider struct { + noop.TracerProvider + // ... + } + +It is strongly recommended that authors only embed +[go.opentelemetry.io/otel/trace/noop] if they choose this default behavior. +That implementation is the only one OpenTelemetry authors can guarantee will +fully implement all the API interfaces when a user updates their API. +*/ +package trace // import "go.opentelemetry.io/otel/trace" diff --git a/go-controller/vendor/go.opentelemetry.io/otel/trace/embedded/README.md b/go-controller/vendor/go.opentelemetry.io/otel/trace/embedded/README.md new file mode 100644 index 0000000000..7754a239ee --- /dev/null +++ b/go-controller/vendor/go.opentelemetry.io/otel/trace/embedded/README.md @@ -0,0 +1,3 @@ +# Trace Embedded + +[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel/trace/embedded)](https://pkg.go.dev/go.opentelemetry.io/otel/trace/embedded) diff --git a/go-controller/vendor/go.opentelemetry.io/otel/trace/embedded/embedded.go b/go-controller/vendor/go.opentelemetry.io/otel/trace/embedded/embedded.go new file mode 100644 index 0000000000..3e359a00bf --- /dev/null +++ b/go-controller/vendor/go.opentelemetry.io/otel/trace/embedded/embedded.go @@ -0,0 +1,45 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// Package embedded provides interfaces embedded within the [OpenTelemetry +// trace API]. +// +// Implementers of the [OpenTelemetry trace API] can embed the relevant type +// from this package into their implementation directly. Doing so will result +// in a compilation error for users when the [OpenTelemetry trace API] is +// extended (which is something that can happen without a major version bump of +// the API package). +// +// [OpenTelemetry trace API]: https://pkg.go.dev/go.opentelemetry.io/otel/trace +package embedded // import "go.opentelemetry.io/otel/trace/embedded" + +// TracerProvider is embedded in +// [go.opentelemetry.io/otel/trace.TracerProvider]. +// +// Embed this interface in your implementation of the +// [go.opentelemetry.io/otel/trace.TracerProvider] if you want users to +// experience a compilation error, signaling they need to update to your latest +// implementation, when the [go.opentelemetry.io/otel/trace.TracerProvider] +// interface is extended (which is something that can happen without a major +// version bump of the API package). +type TracerProvider interface{ tracerProvider() } + +// Tracer is embedded in [go.opentelemetry.io/otel/trace.Tracer]. +// +// Embed this interface in your implementation of the +// [go.opentelemetry.io/otel/trace.Tracer] if you want users to experience a +// compilation error, signaling they need to update to your latest +// implementation, when the [go.opentelemetry.io/otel/trace.Tracer] interface +// is extended (which is something that can happen without a major version bump +// of the API package). +type Tracer interface{ tracer() } + +// Span is embedded in [go.opentelemetry.io/otel/trace.Span]. +// +// Embed this interface in your implementation of the +// [go.opentelemetry.io/otel/trace.Span] if you want users to experience a +// compilation error, signaling they need to update to your latest +// implementation, when the [go.opentelemetry.io/otel/trace.Span] interface is +// extended (which is something that can happen without a major version bump of +// the API package). +type Span interface{ span() } diff --git a/go-controller/vendor/go.opentelemetry.io/otel/trace/nonrecording.go b/go-controller/vendor/go.opentelemetry.io/otel/trace/nonrecording.go new file mode 100644 index 0000000000..c00221e7be --- /dev/null +++ b/go-controller/vendor/go.opentelemetry.io/otel/trace/nonrecording.go @@ -0,0 +1,16 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package trace // import "go.opentelemetry.io/otel/trace" + +// nonRecordingSpan is a minimal implementation of a Span that wraps a +// SpanContext. It performs no operations other than to return the wrapped +// SpanContext. +type nonRecordingSpan struct { + noopSpan + + sc SpanContext +} + +// SpanContext returns the wrapped SpanContext. +func (s nonRecordingSpan) SpanContext() SpanContext { return s.sc } diff --git a/go-controller/vendor/go.opentelemetry.io/otel/trace/noop.go b/go-controller/vendor/go.opentelemetry.io/otel/trace/noop.go new file mode 100644 index 0000000000..ca20e9997a --- /dev/null +++ b/go-controller/vendor/go.opentelemetry.io/otel/trace/noop.go @@ -0,0 +1,85 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package trace // import "go.opentelemetry.io/otel/trace" + +import ( + "context" + + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/codes" + "go.opentelemetry.io/otel/trace/embedded" +) + +// NewNoopTracerProvider returns an implementation of TracerProvider that +// performs no operations. The Tracer and Spans created from the returned +// TracerProvider also perform no operations. +// +// Deprecated: Use [go.opentelemetry.io/otel/trace/noop.NewTracerProvider] +// instead. +func NewNoopTracerProvider() TracerProvider { + return noopTracerProvider{} +} + +type noopTracerProvider struct{ embedded.TracerProvider } + +var _ TracerProvider = noopTracerProvider{} + +// Tracer returns noop implementation of Tracer. +func (p noopTracerProvider) Tracer(string, ...TracerOption) Tracer { + return noopTracer{} +} + +// noopTracer is an implementation of Tracer that performs no operations. +type noopTracer struct{ embedded.Tracer } + +var _ Tracer = noopTracer{} + +// Start carries forward a non-recording Span, if one is present in the context, otherwise it +// creates a no-op Span. +func (t noopTracer) Start(ctx context.Context, name string, _ ...SpanStartOption) (context.Context, Span) { + span := SpanFromContext(ctx) + if _, ok := span.(nonRecordingSpan); !ok { + // span is likely already a noopSpan, but let's be sure + span = noopSpanInstance + } + return ContextWithSpan(ctx, span), span +} + +// noopSpan is an implementation of Span that performs no operations. +type noopSpan struct{ embedded.Span } + +var noopSpanInstance Span = noopSpan{} + +// SpanContext returns an empty span context. +func (noopSpan) SpanContext() SpanContext { return SpanContext{} } + +// IsRecording always returns false. +func (noopSpan) IsRecording() bool { return false } + +// SetStatus does nothing. +func (noopSpan) SetStatus(codes.Code, string) {} + +// SetError does nothing. +func (noopSpan) SetError(bool) {} + +// SetAttributes does nothing. +func (noopSpan) SetAttributes(...attribute.KeyValue) {} + +// End does nothing. +func (noopSpan) End(...SpanEndOption) {} + +// RecordError does nothing. +func (noopSpan) RecordError(error, ...EventOption) {} + +// AddEvent does nothing. +func (noopSpan) AddEvent(string, ...EventOption) {} + +// AddLink does nothing. +func (noopSpan) AddLink(Link) {} + +// SetName does nothing. +func (noopSpan) SetName(string) {} + +// TracerProvider returns a no-op TracerProvider. +func (noopSpan) TracerProvider() TracerProvider { return noopTracerProvider{} } diff --git a/go-controller/vendor/go.opentelemetry.io/otel/trace/provider.go b/go-controller/vendor/go.opentelemetry.io/otel/trace/provider.go new file mode 100644 index 0000000000..ef85cb70c6 --- /dev/null +++ b/go-controller/vendor/go.opentelemetry.io/otel/trace/provider.go @@ -0,0 +1,59 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package trace // import "go.opentelemetry.io/otel/trace" + +import "go.opentelemetry.io/otel/trace/embedded" + +// TracerProvider provides Tracers that are used by instrumentation code to +// trace computational workflows. +// +// A TracerProvider is the collection destination of all Spans from Tracers it +// provides, it represents a unique telemetry collection pipeline. How that +// pipeline is defined, meaning how those Spans are collected, processed, and +// where they are exported, depends on its implementation. Instrumentation +// authors do not need to define this implementation, rather just use the +// provided Tracers to instrument code. +// +// Commonly, instrumentation code will accept a TracerProvider implementation +// at runtime from its users or it can simply use the globally registered one +// (see https://pkg.go.dev/go.opentelemetry.io/otel#GetTracerProvider). +// +// Warning: Methods may be added to this interface in minor releases. See +// package documentation on API implementation for information on how to set +// default behavior for unimplemented methods. +type TracerProvider interface { + // Users of the interface can ignore this. This embedded type is only used + // by implementations of this interface. See the "API Implementations" + // section of the package documentation for more information. + embedded.TracerProvider + + // Tracer returns a unique Tracer scoped to be used by instrumentation code + // to trace computational workflows. The scope and identity of that + // instrumentation code is uniquely defined by the name and options passed. + // + // The passed name needs to uniquely identify instrumentation code. + // Therefore, it is recommended that name is the Go package name of the + // library providing instrumentation (note: not the code being + // instrumented). Instrumentation libraries can have multiple versions, + // therefore, the WithInstrumentationVersion option should be used to + // distinguish these different codebases. Additionally, instrumentation + // libraries may sometimes use traces to communicate different domains of + // workflow data (i.e. using spans to communicate workflow events only). If + // this is the case, the WithScopeAttributes option should be used to + // uniquely identify Tracers that handle the different domains of workflow + // data. + // + // If the same name and options are passed multiple times, the same Tracer + // will be returned (it is up to the implementation if this will be the + // same underlying instance of that Tracer or not). It is not necessary to + // call this multiple times with the same name and options to get an + // up-to-date Tracer. All implementations will ensure any TracerProvider + // configuration changes are propagated to all provided Tracers. + // + // If name is empty, then an implementation defined default name will be + // used instead. + // + // This method is safe to call concurrently. + Tracer(name string, options ...TracerOption) Tracer +} diff --git a/go-controller/vendor/go.opentelemetry.io/otel/trace/span.go b/go-controller/vendor/go.opentelemetry.io/otel/trace/span.go new file mode 100644 index 0000000000..d3aa476ee1 --- /dev/null +++ b/go-controller/vendor/go.opentelemetry.io/otel/trace/span.go @@ -0,0 +1,177 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package trace // import "go.opentelemetry.io/otel/trace" + +import ( + "context" + + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/codes" + "go.opentelemetry.io/otel/trace/embedded" +) + +// Span is the individual component of a trace. It represents a single named +// and timed operation of a workflow that is traced. A Tracer is used to +// create a Span and it is then up to the operation the Span represents to +// properly end the Span when the operation itself ends. +// +// Warning: Methods may be added to this interface in minor releases. See +// package documentation on API implementation for information on how to set +// default behavior for unimplemented methods. +type Span interface { + // Users of the interface can ignore this. This embedded type is only used + // by implementations of this interface. See the "API Implementations" + // section of the package documentation for more information. + embedded.Span + + // End completes the Span. The Span is considered complete and ready to be + // delivered through the rest of the telemetry pipeline after this method + // is called. Therefore, updates to the Span are not allowed after this + // method has been called. + End(options ...SpanEndOption) + + // AddEvent adds an event with the provided name and options. + AddEvent(name string, options ...EventOption) + + // AddLink adds a link. + // Adding links at span creation using WithLinks is preferred to calling AddLink + // later, for contexts that are available during span creation, because head + // sampling decisions can only consider information present during span creation. + AddLink(link Link) + + // IsRecording returns the recording state of the Span. It will return + // true if the Span is active and events can be recorded. + IsRecording() bool + + // RecordError will record err as an exception span event for this span. An + // additional call to SetStatus is required if the Status of the Span should + // be set to Error, as this method does not change the Span status. If this + // span is not being recorded or err is nil then this method does nothing. + RecordError(err error, options ...EventOption) + + // SpanContext returns the SpanContext of the Span. The returned SpanContext + // is usable even after the End method has been called for the Span. + SpanContext() SpanContext + + // SetStatus sets the status of the Span in the form of a code and a + // description, provided the status hasn't already been set to a higher + // value before (OK > Error > Unset). The description is only included in a + // status when the code is for an error. + SetStatus(code codes.Code, description string) + + // SetName sets the Span name. + SetName(name string) + + // SetAttributes sets kv as attributes of the Span. If a key from kv + // already exists for an attribute of the Span it will be overwritten with + // the value contained in kv. + SetAttributes(kv ...attribute.KeyValue) + + // TracerProvider returns a TracerProvider that can be used to generate + // additional Spans on the same telemetry pipeline as the current Span. + TracerProvider() TracerProvider +} + +// Link is the relationship between two Spans. The relationship can be within +// the same Trace or across different Traces. +// +// For example, a Link is used in the following situations: +// +// 1. Batch Processing: A batch of operations may contain operations +// associated with one or more traces/spans. Since there can only be one +// parent SpanContext, a Link is used to keep reference to the +// SpanContext of all operations in the batch. +// 2. Public Endpoint: A SpanContext for an in incoming client request on a +// public endpoint should be considered untrusted. In such a case, a new +// trace with its own identity and sampling decision needs to be created, +// but this new trace needs to be related to the original trace in some +// form. A Link is used to keep reference to the original SpanContext and +// track the relationship. +type Link struct { + // SpanContext of the linked Span. + SpanContext SpanContext + + // Attributes describe the aspects of the link. + Attributes []attribute.KeyValue +} + +// LinkFromContext returns a link encapsulating the SpanContext in the provided +// ctx. +func LinkFromContext(ctx context.Context, attrs ...attribute.KeyValue) Link { + return Link{ + SpanContext: SpanContextFromContext(ctx), + Attributes: attrs, + } +} + +// SpanKind is the role a Span plays in a Trace. +type SpanKind int + +// As a convenience, these match the proto definition, see +// https://github.com/open-telemetry/opentelemetry-proto/blob/30d237e1ff3ab7aa50e0922b5bebdd93505090af/opentelemetry/proto/trace/v1/trace.proto#L101-L129 +// +// The unspecified value is not a valid `SpanKind`. Use `ValidateSpanKind()` +// to coerce a span kind to a valid value. +const ( + // SpanKindUnspecified is an unspecified SpanKind and is not a valid + // SpanKind. SpanKindUnspecified should be replaced with SpanKindInternal + // if it is received. + SpanKindUnspecified SpanKind = 0 + // SpanKindInternal is a SpanKind for a Span that represents an internal + // operation within an application. + SpanKindInternal SpanKind = 1 + // SpanKindServer is a SpanKind for a Span that represents the operation + // of handling a request from a client. + SpanKindServer SpanKind = 2 + // SpanKindClient is a SpanKind for a Span that represents the operation + // of client making a request to a server. + SpanKindClient SpanKind = 3 + // SpanKindProducer is a SpanKind for a Span that represents the operation + // of a producer sending a message to a message broker. Unlike + // SpanKindClient and SpanKindServer, there is often no direct + // relationship between this kind of Span and a SpanKindConsumer kind. A + // SpanKindProducer Span will end once the message is accepted by the + // message broker which might not overlap with the processing of that + // message. + SpanKindProducer SpanKind = 4 + // SpanKindConsumer is a SpanKind for a Span that represents the operation + // of a consumer receiving a message from a message broker. Like + // SpanKindProducer Spans, there is often no direct relationship between + // this Span and the Span that produced the message. + SpanKindConsumer SpanKind = 5 +) + +// ValidateSpanKind returns a valid span kind value. This will coerce +// invalid values into the default value, SpanKindInternal. +func ValidateSpanKind(spanKind SpanKind) SpanKind { + switch spanKind { + case SpanKindInternal, + SpanKindServer, + SpanKindClient, + SpanKindProducer, + SpanKindConsumer: + // valid + return spanKind + default: + return SpanKindInternal + } +} + +// String returns the specified name of the SpanKind in lower-case. +func (sk SpanKind) String() string { + switch sk { + case SpanKindInternal: + return "internal" + case SpanKindServer: + return "server" + case SpanKindClient: + return "client" + case SpanKindProducer: + return "producer" + case SpanKindConsumer: + return "consumer" + default: + return "unspecified" + } +} diff --git a/go-controller/vendor/go.opentelemetry.io/otel/trace/trace.go b/go-controller/vendor/go.opentelemetry.io/otel/trace/trace.go new file mode 100644 index 0000000000..d49adf671b --- /dev/null +++ b/go-controller/vendor/go.opentelemetry.io/otel/trace/trace.go @@ -0,0 +1,323 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package trace // import "go.opentelemetry.io/otel/trace" + +import ( + "bytes" + "encoding/hex" + "encoding/json" +) + +const ( + // FlagsSampled is a bitmask with the sampled bit set. A SpanContext + // with the sampling bit set means the span is sampled. + FlagsSampled = TraceFlags(0x01) + + errInvalidHexID errorConst = "trace-id and span-id can only contain [0-9a-f] characters, all lowercase" + + errInvalidTraceIDLength errorConst = "hex encoded trace-id must have length equals to 32" + errNilTraceID errorConst = "trace-id can't be all zero" + + errInvalidSpanIDLength errorConst = "hex encoded span-id must have length equals to 16" + errNilSpanID errorConst = "span-id can't be all zero" +) + +type errorConst string + +func (e errorConst) Error() string { + return string(e) +} + +// TraceID is a unique identity of a trace. +// nolint:revive // revive complains about stutter of `trace.TraceID`. +type TraceID [16]byte + +var ( + nilTraceID TraceID + _ json.Marshaler = nilTraceID +) + +// IsValid checks whether the trace TraceID is valid. A valid trace ID does +// not consist of zeros only. +func (t TraceID) IsValid() bool { + return !bytes.Equal(t[:], nilTraceID[:]) +} + +// MarshalJSON implements a custom marshal function to encode TraceID +// as a hex string. +func (t TraceID) MarshalJSON() ([]byte, error) { + return json.Marshal(t.String()) +} + +// String returns the hex string representation form of a TraceID. +func (t TraceID) String() string { + return hex.EncodeToString(t[:]) +} + +// SpanID is a unique identity of a span in a trace. +type SpanID [8]byte + +var ( + nilSpanID SpanID + _ json.Marshaler = nilSpanID +) + +// IsValid checks whether the SpanID is valid. A valid SpanID does not consist +// of zeros only. +func (s SpanID) IsValid() bool { + return !bytes.Equal(s[:], nilSpanID[:]) +} + +// MarshalJSON implements a custom marshal function to encode SpanID +// as a hex string. +func (s SpanID) MarshalJSON() ([]byte, error) { + return json.Marshal(s.String()) +} + +// String returns the hex string representation form of a SpanID. +func (s SpanID) String() string { + return hex.EncodeToString(s[:]) +} + +// TraceIDFromHex returns a TraceID from a hex string if it is compliant with +// the W3C trace-context specification. See more at +// https://www.w3.org/TR/trace-context/#trace-id +// nolint:revive // revive complains about stutter of `trace.TraceIDFromHex`. +func TraceIDFromHex(h string) (TraceID, error) { + t := TraceID{} + if len(h) != 32 { + return t, errInvalidTraceIDLength + } + + if err := decodeHex(h, t[:]); err != nil { + return t, err + } + + if !t.IsValid() { + return t, errNilTraceID + } + return t, nil +} + +// SpanIDFromHex returns a SpanID from a hex string if it is compliant +// with the w3c trace-context specification. +// See more at https://www.w3.org/TR/trace-context/#parent-id +func SpanIDFromHex(h string) (SpanID, error) { + s := SpanID{} + if len(h) != 16 { + return s, errInvalidSpanIDLength + } + + if err := decodeHex(h, s[:]); err != nil { + return s, err + } + + if !s.IsValid() { + return s, errNilSpanID + } + return s, nil +} + +func decodeHex(h string, b []byte) error { + for _, r := range h { + switch { + case 'a' <= r && r <= 'f': + continue + case '0' <= r && r <= '9': + continue + default: + return errInvalidHexID + } + } + + decoded, err := hex.DecodeString(h) + if err != nil { + return err + } + + copy(b, decoded) + return nil +} + +// TraceFlags contains flags that can be set on a SpanContext. +type TraceFlags byte //nolint:revive // revive complains about stutter of `trace.TraceFlags`. + +// IsSampled returns if the sampling bit is set in the TraceFlags. +func (tf TraceFlags) IsSampled() bool { + return tf&FlagsSampled == FlagsSampled +} + +// WithSampled sets the sampling bit in a new copy of the TraceFlags. +func (tf TraceFlags) WithSampled(sampled bool) TraceFlags { // nolint:revive // sampled is not a control flag. + if sampled { + return tf | FlagsSampled + } + + return tf &^ FlagsSampled +} + +// MarshalJSON implements a custom marshal function to encode TraceFlags +// as a hex string. +func (tf TraceFlags) MarshalJSON() ([]byte, error) { + return json.Marshal(tf.String()) +} + +// String returns the hex string representation form of TraceFlags. +func (tf TraceFlags) String() string { + return hex.EncodeToString([]byte{byte(tf)}[:]) +} + +// SpanContextConfig contains mutable fields usable for constructing +// an immutable SpanContext. +type SpanContextConfig struct { + TraceID TraceID + SpanID SpanID + TraceFlags TraceFlags + TraceState TraceState + Remote bool +} + +// NewSpanContext constructs a SpanContext using values from the provided +// SpanContextConfig. +func NewSpanContext(config SpanContextConfig) SpanContext { + return SpanContext{ + traceID: config.TraceID, + spanID: config.SpanID, + traceFlags: config.TraceFlags, + traceState: config.TraceState, + remote: config.Remote, + } +} + +// SpanContext contains identifying trace information about a Span. +type SpanContext struct { + traceID TraceID + spanID SpanID + traceFlags TraceFlags + traceState TraceState + remote bool +} + +var _ json.Marshaler = SpanContext{} + +// IsValid returns if the SpanContext is valid. A valid span context has a +// valid TraceID and SpanID. +func (sc SpanContext) IsValid() bool { + return sc.HasTraceID() && sc.HasSpanID() +} + +// IsRemote indicates whether the SpanContext represents a remotely-created Span. +func (sc SpanContext) IsRemote() bool { + return sc.remote +} + +// WithRemote returns a copy of sc with the Remote property set to remote. +func (sc SpanContext) WithRemote(remote bool) SpanContext { + return SpanContext{ + traceID: sc.traceID, + spanID: sc.spanID, + traceFlags: sc.traceFlags, + traceState: sc.traceState, + remote: remote, + } +} + +// TraceID returns the TraceID from the SpanContext. +func (sc SpanContext) TraceID() TraceID { + return sc.traceID +} + +// HasTraceID checks if the SpanContext has a valid TraceID. +func (sc SpanContext) HasTraceID() bool { + return sc.traceID.IsValid() +} + +// WithTraceID returns a new SpanContext with the TraceID replaced. +func (sc SpanContext) WithTraceID(traceID TraceID) SpanContext { + return SpanContext{ + traceID: traceID, + spanID: sc.spanID, + traceFlags: sc.traceFlags, + traceState: sc.traceState, + remote: sc.remote, + } +} + +// SpanID returns the SpanID from the SpanContext. +func (sc SpanContext) SpanID() SpanID { + return sc.spanID +} + +// HasSpanID checks if the SpanContext has a valid SpanID. +func (sc SpanContext) HasSpanID() bool { + return sc.spanID.IsValid() +} + +// WithSpanID returns a new SpanContext with the SpanID replaced. +func (sc SpanContext) WithSpanID(spanID SpanID) SpanContext { + return SpanContext{ + traceID: sc.traceID, + spanID: spanID, + traceFlags: sc.traceFlags, + traceState: sc.traceState, + remote: sc.remote, + } +} + +// TraceFlags returns the flags from the SpanContext. +func (sc SpanContext) TraceFlags() TraceFlags { + return sc.traceFlags +} + +// IsSampled returns if the sampling bit is set in the SpanContext's TraceFlags. +func (sc SpanContext) IsSampled() bool { + return sc.traceFlags.IsSampled() +} + +// WithTraceFlags returns a new SpanContext with the TraceFlags replaced. +func (sc SpanContext) WithTraceFlags(flags TraceFlags) SpanContext { + return SpanContext{ + traceID: sc.traceID, + spanID: sc.spanID, + traceFlags: flags, + traceState: sc.traceState, + remote: sc.remote, + } +} + +// TraceState returns the TraceState from the SpanContext. +func (sc SpanContext) TraceState() TraceState { + return sc.traceState +} + +// WithTraceState returns a new SpanContext with the TraceState replaced. +func (sc SpanContext) WithTraceState(state TraceState) SpanContext { + return SpanContext{ + traceID: sc.traceID, + spanID: sc.spanID, + traceFlags: sc.traceFlags, + traceState: state, + remote: sc.remote, + } +} + +// Equal is a predicate that determines whether two SpanContext values are equal. +func (sc SpanContext) Equal(other SpanContext) bool { + return sc.traceID == other.traceID && + sc.spanID == other.spanID && + sc.traceFlags == other.traceFlags && + sc.traceState.String() == other.traceState.String() && + sc.remote == other.remote +} + +// MarshalJSON implements a custom marshal function to encode a SpanContext. +func (sc SpanContext) MarshalJSON() ([]byte, error) { + return json.Marshal(SpanContextConfig{ + TraceID: sc.traceID, + SpanID: sc.spanID, + TraceFlags: sc.traceFlags, + TraceState: sc.traceState, + Remote: sc.remote, + }) +} diff --git a/go-controller/vendor/go.opentelemetry.io/otel/trace/tracer.go b/go-controller/vendor/go.opentelemetry.io/otel/trace/tracer.go new file mode 100644 index 0000000000..77952d2a0b --- /dev/null +++ b/go-controller/vendor/go.opentelemetry.io/otel/trace/tracer.go @@ -0,0 +1,37 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package trace // import "go.opentelemetry.io/otel/trace" + +import ( + "context" + + "go.opentelemetry.io/otel/trace/embedded" +) + +// Tracer is the creator of Spans. +// +// Warning: Methods may be added to this interface in minor releases. See +// package documentation on API implementation for information on how to set +// default behavior for unimplemented methods. +type Tracer interface { + // Users of the interface can ignore this. This embedded type is only used + // by implementations of this interface. See the "API Implementations" + // section of the package documentation for more information. + embedded.Tracer + + // Start creates a span and a context.Context containing the newly-created span. + // + // If the context.Context provided in `ctx` contains a Span then the newly-created + // Span will be a child of that span, otherwise it will be a root span. This behavior + // can be overridden by providing `WithNewRoot()` as a SpanOption, causing the + // newly-created Span to be a root span even if `ctx` contains a Span. + // + // When creating a Span it is recommended to provide all known span attributes using + // the `WithAttributes()` SpanOption as samplers will only have access to the + // attributes provided when a Span is created. + // + // Any Span that is created MUST also be ended. This is the responsibility of the user. + // Implementations of this API may leak memory or other resources if Spans are not ended. + Start(ctx context.Context, spanName string, opts ...SpanStartOption) (context.Context, Span) +} diff --git a/go-controller/vendor/go.opentelemetry.io/otel/trace/tracestate.go b/go-controller/vendor/go.opentelemetry.io/otel/trace/tracestate.go new file mode 100644 index 0000000000..dc5e34cad0 --- /dev/null +++ b/go-controller/vendor/go.opentelemetry.io/otel/trace/tracestate.go @@ -0,0 +1,330 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package trace // import "go.opentelemetry.io/otel/trace" + +import ( + "encoding/json" + "fmt" + "strings" +) + +const ( + maxListMembers = 32 + + listDelimiters = "," + memberDelimiter = "=" + + errInvalidKey errorConst = "invalid tracestate key" + errInvalidValue errorConst = "invalid tracestate value" + errInvalidMember errorConst = "invalid tracestate list-member" + errMemberNumber errorConst = "too many list-members in tracestate" + errDuplicate errorConst = "duplicate list-member in tracestate" +) + +type member struct { + Key string + Value string +} + +// according to (chr = %x20 / (nblk-char = %x21-2B / %x2D-3C / %x3E-7E) ) +// means (chr = %x20-2B / %x2D-3C / %x3E-7E) . +func checkValueChar(v byte) bool { + return v >= '\x20' && v <= '\x7e' && v != '\x2c' && v != '\x3d' +} + +// according to (nblk-chr = %x21-2B / %x2D-3C / %x3E-7E) . +func checkValueLast(v byte) bool { + return v >= '\x21' && v <= '\x7e' && v != '\x2c' && v != '\x3d' +} + +// based on the W3C Trace Context specification +// +// value = (0*255(chr)) nblk-chr +// nblk-chr = %x21-2B / %x2D-3C / %x3E-7E +// chr = %x20 / nblk-chr +// +// see https://www.w3.org/TR/trace-context-1/#value +func checkValue(val string) bool { + n := len(val) + if n == 0 || n > 256 { + return false + } + for i := 0; i < n-1; i++ { + if !checkValueChar(val[i]) { + return false + } + } + return checkValueLast(val[n-1]) +} + +func checkKeyRemain(key string) bool { + // ( lcalpha / DIGIT / "_" / "-"/ "*" / "/" ) + for _, v := range key { + if isAlphaNum(byte(v)) { + continue + } + switch v { + case '_', '-', '*', '/': + continue + } + return false + } + return true +} + +// according to +// +// simple-key = lcalpha (0*255( lcalpha / DIGIT / "_" / "-"/ "*" / "/" )) +// system-id = lcalpha (0*13( lcalpha / DIGIT / "_" / "-"/ "*" / "/" )) +// +// param n is remain part length, should be 255 in simple-key or 13 in system-id. +func checkKeyPart(key string, n int) bool { + if len(key) == 0 { + return false + } + first := key[0] // key's first char + ret := len(key[1:]) <= n + ret = ret && first >= 'a' && first <= 'z' + return ret && checkKeyRemain(key[1:]) +} + +func isAlphaNum(c byte) bool { + if c >= 'a' && c <= 'z' { + return true + } + return c >= '0' && c <= '9' +} + +// according to +// +// tenant-id = ( lcalpha / DIGIT ) 0*240( lcalpha / DIGIT / "_" / "-"/ "*" / "/" ) +// +// param n is remain part length, should be 240 exactly. +func checkKeyTenant(key string, n int) bool { + if len(key) == 0 { + return false + } + return isAlphaNum(key[0]) && len(key[1:]) <= n && checkKeyRemain(key[1:]) +} + +// based on the W3C Trace Context specification +// +// key = simple-key / multi-tenant-key +// simple-key = lcalpha (0*255( lcalpha / DIGIT / "_" / "-"/ "*" / "/" )) +// multi-tenant-key = tenant-id "@" system-id +// tenant-id = ( lcalpha / DIGIT ) (0*240( lcalpha / DIGIT / "_" / "-"/ "*" / "/" )) +// system-id = lcalpha (0*13( lcalpha / DIGIT / "_" / "-"/ "*" / "/" )) +// lcalpha = %x61-7A ; a-z +// +// see https://www.w3.org/TR/trace-context-1/#tracestate-header. +func checkKey(key string) bool { + tenant, system, ok := strings.Cut(key, "@") + if !ok { + return checkKeyPart(key, 255) + } + return checkKeyTenant(tenant, 240) && checkKeyPart(system, 13) +} + +func newMember(key, value string) (member, error) { + if !checkKey(key) { + return member{}, errInvalidKey + } + if !checkValue(value) { + return member{}, errInvalidValue + } + return member{Key: key, Value: value}, nil +} + +func parseMember(m string) (member, error) { + key, val, ok := strings.Cut(m, memberDelimiter) + if !ok { + return member{}, fmt.Errorf("%w: %s", errInvalidMember, m) + } + key = strings.TrimLeft(key, " \t") + val = strings.TrimRight(val, " \t") + result, e := newMember(key, val) + if e != nil { + return member{}, fmt.Errorf("%w: %s", errInvalidMember, m) + } + return result, nil +} + +// String encodes member into a string compliant with the W3C Trace Context +// specification. +func (m member) String() string { + return m.Key + "=" + m.Value +} + +// TraceState provides additional vendor-specific trace identification +// information across different distributed tracing systems. It represents an +// immutable list consisting of key/value pairs, each pair is referred to as a +// list-member. +// +// TraceState conforms to the W3C Trace Context specification +// (https://www.w3.org/TR/trace-context-1). All operations that create or copy +// a TraceState do so by validating all input and will only produce TraceState +// that conform to the specification. Specifically, this means that all +// list-member's key/value pairs are valid, no duplicate list-members exist, +// and the maximum number of list-members (32) is not exceeded. +type TraceState struct { //nolint:revive // revive complains about stutter of `trace.TraceState` + // list is the members in order. + list []member +} + +var _ json.Marshaler = TraceState{} + +// ParseTraceState attempts to decode a TraceState from the passed +// string. It returns an error if the input is invalid according to the W3C +// Trace Context specification. +func ParseTraceState(ts string) (TraceState, error) { + if ts == "" { + return TraceState{}, nil + } + + wrapErr := func(err error) error { + return fmt.Errorf("failed to parse tracestate: %w", err) + } + + var members []member + found := make(map[string]struct{}) + for ts != "" { + var memberStr string + memberStr, ts, _ = strings.Cut(ts, listDelimiters) + if len(memberStr) == 0 { + continue + } + + m, err := parseMember(memberStr) + if err != nil { + return TraceState{}, wrapErr(err) + } + + if _, ok := found[m.Key]; ok { + return TraceState{}, wrapErr(errDuplicate) + } + found[m.Key] = struct{}{} + + members = append(members, m) + if n := len(members); n > maxListMembers { + return TraceState{}, wrapErr(errMemberNumber) + } + } + + return TraceState{list: members}, nil +} + +// MarshalJSON marshals the TraceState into JSON. +func (ts TraceState) MarshalJSON() ([]byte, error) { + return json.Marshal(ts.String()) +} + +// String encodes the TraceState into a string compliant with the W3C +// Trace Context specification. The returned string will be invalid if the +// TraceState contains any invalid members. +func (ts TraceState) String() string { + if len(ts.list) == 0 { + return "" + } + var n int + n += len(ts.list) // member delimiters: '=' + n += len(ts.list) - 1 // list delimiters: ',' + for _, mem := range ts.list { + n += len(mem.Key) + n += len(mem.Value) + } + + var sb strings.Builder + sb.Grow(n) + _, _ = sb.WriteString(ts.list[0].Key) + _ = sb.WriteByte('=') + _, _ = sb.WriteString(ts.list[0].Value) + for i := 1; i < len(ts.list); i++ { + _ = sb.WriteByte(listDelimiters[0]) + _, _ = sb.WriteString(ts.list[i].Key) + _ = sb.WriteByte('=') + _, _ = sb.WriteString(ts.list[i].Value) + } + return sb.String() +} + +// Get returns the value paired with key from the corresponding TraceState +// list-member if it exists, otherwise an empty string is returned. +func (ts TraceState) Get(key string) string { + for _, member := range ts.list { + if member.Key == key { + return member.Value + } + } + + return "" +} + +// Walk walks all key value pairs in the TraceState by calling f +// Iteration stops if f returns false. +func (ts TraceState) Walk(f func(key, value string) bool) { + for _, m := range ts.list { + if !f(m.Key, m.Value) { + break + } + } +} + +// Insert adds a new list-member defined by the key/value pair to the +// TraceState. If a list-member already exists for the given key, that +// list-member's value is updated. The new or updated list-member is always +// moved to the beginning of the TraceState as specified by the W3C Trace +// Context specification. +// +// If key or value are invalid according to the W3C Trace Context +// specification an error is returned with the original TraceState. +// +// If adding a new list-member means the TraceState would have more members +// then is allowed, the new list-member will be inserted and the right-most +// list-member will be dropped in the returned TraceState. +func (ts TraceState) Insert(key, value string) (TraceState, error) { + m, err := newMember(key, value) + if err != nil { + return ts, err + } + n := len(ts.list) + found := n + for i := range ts.list { + if ts.list[i].Key == key { + found = i + } + } + cTS := TraceState{} + if found == n && n < maxListMembers { + cTS.list = make([]member, n+1) + } else { + cTS.list = make([]member, n) + } + cTS.list[0] = m + // When the number of members exceeds capacity, drop the "right-most". + copy(cTS.list[1:], ts.list[0:found]) + if found < n { + copy(cTS.list[1+found:], ts.list[found+1:]) + } + return cTS, nil +} + +// Delete returns a copy of the TraceState with the list-member identified by +// key removed. +func (ts TraceState) Delete(key string) TraceState { + members := make([]member, ts.Len()) + copy(members, ts.list) + for i, member := range ts.list { + if member.Key == key { + members = append(members[:i], members[i+1:]...) + // TraceState should contain no duplicate members. + break + } + } + return TraceState{list: members} +} + +// Len returns the number of list-members in the TraceState. +func (ts TraceState) Len() int { + return len(ts.list) +} diff --git a/go-controller/vendor/google.golang.org/grpc/CONTRIBUTING.md b/go-controller/vendor/google.golang.org/grpc/CONTRIBUTING.md index 0854d298e4..d9bfa6e1e7 100644 --- a/go-controller/vendor/google.golang.org/grpc/CONTRIBUTING.md +++ b/go-controller/vendor/google.golang.org/grpc/CONTRIBUTING.md @@ -4,7 +4,7 @@ We definitely welcome your patches and contributions to gRPC! Please read the gR organization's [governance rules](https://github.com/grpc/grpc-community/blob/master/governance.md) and [contribution guidelines](https://github.com/grpc/grpc-community/blob/master/CONTRIBUTING.md) before proceeding. -If you are new to github, please start by reading [Pull Request howto](https://help.github.com/articles/about-pull-requests/) +If you are new to GitHub, please start by reading [Pull Request howto](https://help.github.com/articles/about-pull-requests/) ## Legal requirements @@ -25,8 +25,8 @@ How to get your contributions merged smoothly and quickly. is a great place to start. These issues are well-documented and usually can be resolved with a single pull request. -- If you are adding a new file, make sure it has the copyright message template - at the top as a comment. You can copy over the message from an existing file +- If you are adding a new file, make sure it has the copyright message template + at the top as a comment. You can copy over the message from an existing file and update the year. - The grpc package should only depend on standard Go packages and a small number @@ -39,12 +39,12 @@ How to get your contributions merged smoothly and quickly. proposal](https://github.com/grpc/proposal). - Provide a good **PR description** as a record of **what** change is being made - and **why** it was made. Link to a github issue if it exists. + and **why** it was made. Link to a GitHub issue if it exists. -- If you want to fix formatting or style, consider whether your changes are an - obvious improvement or might be considered a personal preference. If a style - change is based on preference, it likely will not be accepted. If it corrects - widely agreed-upon anti-patterns, then please do create a PR and explain the +- If you want to fix formatting or style, consider whether your changes are an + obvious improvement or might be considered a personal preference. If a style + change is based on preference, it likely will not be accepted. If it corrects + widely agreed-upon anti-patterns, then please do create a PR and explain the benefits of the change. - Unless your PR is trivial, you should expect there will be reviewer comments diff --git a/go-controller/vendor/google.golang.org/grpc/MAINTAINERS.md b/go-controller/vendor/google.golang.org/grpc/MAINTAINERS.md index 6a8a07781a..5d4096d46a 100644 --- a/go-controller/vendor/google.golang.org/grpc/MAINTAINERS.md +++ b/go-controller/vendor/google.golang.org/grpc/MAINTAINERS.md @@ -9,21 +9,28 @@ for general contribution guidelines. ## Maintainers (in alphabetical order) +- [aranjans](https://github.com/aranjans), Google LLC +- [arjan-bal](https://github.com/arjan-bal), Google LLC +- [arvindbr8](https://github.com/arvindbr8), Google LLC - [atollena](https://github.com/atollena), Datadog, Inc. -- [cesarghali](https://github.com/cesarghali), Google LLC - [dfawley](https://github.com/dfawley), Google LLC - [easwars](https://github.com/easwars), Google LLC -- [menghanl](https://github.com/menghanl), Google LLC -- [srini100](https://github.com/srini100), Google LLC +- [erm-g](https://github.com/erm-g), Google LLC +- [gtcooke94](https://github.com/gtcooke94), Google LLC +- [purnesh42h](https://github.com/purnesh42h), Google LLC +- [zasweq](https://github.com/zasweq), Google LLC ## Emeritus Maintainers (in alphabetical order) -- [adelez](https://github.com/adelez), Google LLC -- [canguler](https://github.com/canguler), Google LLC -- [iamqizhao](https://github.com/iamqizhao), Google LLC -- [jadekler](https://github.com/jadekler), Google LLC -- [jtattermusch](https://github.com/jtattermusch), Google LLC -- [lyuxuan](https://github.com/lyuxuan), Google LLC -- [makmukhi](https://github.com/makmukhi), Google LLC -- [matt-kwong](https://github.com/matt-kwong), Google LLC -- [nicolasnoble](https://github.com/nicolasnoble), Google LLC -- [yongni](https://github.com/yongni), Google LLC +- [adelez](https://github.com/adelez) +- [canguler](https://github.com/canguler) +- [cesarghali](https://github.com/cesarghali) +- [iamqizhao](https://github.com/iamqizhao) +- [jeanbza](https://github.com/jeanbza) +- [jtattermusch](https://github.com/jtattermusch) +- [lyuxuan](https://github.com/lyuxuan) +- [makmukhi](https://github.com/makmukhi) +- [matt-kwong](https://github.com/matt-kwong) +- [menghanl](https://github.com/menghanl) +- [nicolasnoble](https://github.com/nicolasnoble) +- [srini100](https://github.com/srini100) +- [yongni](https://github.com/yongni) diff --git a/go-controller/vendor/google.golang.org/grpc/SECURITY.md b/go-controller/vendor/google.golang.org/grpc/SECURITY.md index be6e108705..abab279379 100644 --- a/go-controller/vendor/google.golang.org/grpc/SECURITY.md +++ b/go-controller/vendor/google.golang.org/grpc/SECURITY.md @@ -1,3 +1,3 @@ # Security Policy -For information on gRPC Security Policy and reporting potentional security issues, please see [gRPC CVE Process](https://github.com/grpc/proposal/blob/master/P4-grpc-cve-process.md). +For information on gRPC Security Policy and reporting potential security issues, please see [gRPC CVE Process](https://github.com/grpc/proposal/blob/master/P4-grpc-cve-process.md). diff --git a/go-controller/vendor/google.golang.org/grpc/backoff/backoff.go b/go-controller/vendor/google.golang.org/grpc/backoff/backoff.go index 0787d0b50c..d7b40b7cb6 100644 --- a/go-controller/vendor/google.golang.org/grpc/backoff/backoff.go +++ b/go-controller/vendor/google.golang.org/grpc/backoff/backoff.go @@ -39,7 +39,7 @@ type Config struct { MaxDelay time.Duration } -// DefaultConfig is a backoff configuration with the default values specfied +// DefaultConfig is a backoff configuration with the default values specified // at https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md. // // This should be useful for callers who want to configure backoff with diff --git a/go-controller/vendor/google.golang.org/grpc/balancer/balancer.go b/go-controller/vendor/google.golang.org/grpc/balancer/balancer.go index f391744f72..3a2092f105 100644 --- a/go-controller/vendor/google.golang.org/grpc/balancer/balancer.go +++ b/go-controller/vendor/google.golang.org/grpc/balancer/balancer.go @@ -30,6 +30,7 @@ import ( "google.golang.org/grpc/channelz" "google.golang.org/grpc/connectivity" "google.golang.org/grpc/credentials" + estats "google.golang.org/grpc/experimental/stats" "google.golang.org/grpc/grpclog" "google.golang.org/grpc/internal" "google.golang.org/grpc/metadata" @@ -72,8 +73,21 @@ func unregisterForTesting(name string) { delete(m, name) } +// connectedAddress returns the connected address for a SubConnState. The +// address is only valid if the state is READY. +func connectedAddress(scs SubConnState) resolver.Address { + return scs.connectedAddress +} + +// setConnectedAddress sets the connected address for a SubConnState. +func setConnectedAddress(scs *SubConnState, addr resolver.Address) { + scs.connectedAddress = addr +} + func init() { internal.BalancerUnregister = unregisterForTesting + internal.ConnectedAddress = connectedAddress + internal.SetConnectedAddress = setConnectedAddress } // Get returns the resolver builder registered with the given name. @@ -116,7 +130,7 @@ type SubConn interface { // UpdateAddresses updates the addresses used in this SubConn. // gRPC checks if currently-connected address is still in the new list. // If it's in the list, the connection will be kept. - // If it's not in the list, the connection will gracefully closed, and + // If it's not in the list, the connection will gracefully close, and // a new connection will be created. // // This will trigger a state transition for the SubConn. @@ -128,8 +142,11 @@ type SubConn interface { Connect() // GetOrBuildProducer returns a reference to the existing Producer for this // ProducerBuilder in this SubConn, or, if one does not currently exist, - // creates a new one and returns it. Returns a close function which must - // be called when the Producer is no longer needed. + // creates a new one and returns it. Returns a close function which may be + // called when the Producer is no longer needed. Otherwise the producer + // will automatically be closed upon connection loss or subchannel close. + // Should only be called on a SubConn in state Ready. Otherwise the + // producer will be unable to create streams. GetOrBuildProducer(ProducerBuilder) (p Producer, close func()) // Shutdown shuts down the SubConn gracefully. Any started RPCs will be // allowed to complete. No future calls should be made on the SubConn. @@ -243,6 +260,10 @@ type BuildOptions struct { // same resolver.Target as passed to the resolver. See the documentation for // the resolver.Target type for details about what it contains. Target resolver.Target + // MetricsRecorder is the metrics recorder that balancers can use to record + // metrics. Balancer implementations which do not register metrics on + // metrics registry and record on them can ignore this field. + MetricsRecorder estats.MetricsRecorder } // Builder creates a balancer. @@ -410,6 +431,9 @@ type SubConnState struct { // ConnectionError is set if the ConnectivityState is TransientFailure, // describing the reason the SubConn failed. Otherwise, it is nil. ConnectionError error + // connectedAddr contains the connected address when ConnectivityState is + // Ready. Otherwise, it is indeterminate. + connectedAddress resolver.Address } // ClientConnState describes the state of a ClientConn relevant to the @@ -431,8 +455,10 @@ type ProducerBuilder interface { // Build creates a Producer. The first parameter is always a // grpc.ClientConnInterface (a type to allow creating RPCs/streams on the // associated SubConn), but is declared as `any` to avoid a dependency - // cycle. Should also return a close function that will be called when all - // references to the Producer have been given up. + // cycle. Build also returns a close function that will be called when all + // references to the Producer have been given up for a SubConn, or when a + // connectivity state change occurs on the SubConn. The close function + // should always block until all asynchronous cleanup work is completed. Build(grpcClientConnInterface any) (p Producer, close func()) } diff --git a/go-controller/vendor/google.golang.org/grpc/balancer/base/balancer.go b/go-controller/vendor/google.golang.org/grpc/balancer/base/balancer.go index a7f1eeec8e..d5ed172ae6 100644 --- a/go-controller/vendor/google.golang.org/grpc/balancer/base/balancer.go +++ b/go-controller/vendor/google.golang.org/grpc/balancer/base/balancer.go @@ -36,7 +36,7 @@ type baseBuilder struct { config Config } -func (bb *baseBuilder) Build(cc balancer.ClientConn, opt balancer.BuildOptions) balancer.Balancer { +func (bb *baseBuilder) Build(cc balancer.ClientConn, _ balancer.BuildOptions) balancer.Balancer { bal := &baseBalancer{ cc: cc, pickerBuilder: bb.pickerBuilder, @@ -133,7 +133,7 @@ func (b *baseBalancer) UpdateClientConnState(s balancer.ClientConnState) error { } } // If resolver state contains no addresses, return an error so ClientConn - // will trigger re-resolve. Also records this as an resolver error, so when + // will trigger re-resolve. Also records this as a resolver error, so when // the overall state turns transient failure, the error message will have // the zero address information. if len(s.ResolverState.Addresses) == 0 { @@ -259,6 +259,6 @@ type errPicker struct { err error // Pick() always returns this err. } -func (p *errPicker) Pick(info balancer.PickInfo) (balancer.PickResult, error) { +func (p *errPicker) Pick(balancer.PickInfo) (balancer.PickResult, error) { return balancer.PickResult{}, p.err } diff --git a/go-controller/vendor/google.golang.org/grpc/balancer/pickfirst/internal/internal.go b/go-controller/vendor/google.golang.org/grpc/balancer/pickfirst/internal/internal.go new file mode 100644 index 0000000000..c519789458 --- /dev/null +++ b/go-controller/vendor/google.golang.org/grpc/balancer/pickfirst/internal/internal.go @@ -0,0 +1,24 @@ +/* + * Copyright 2024 gRPC authors. + * + * 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 internal contains code internal to the pickfirst package. +package internal + +import "math/rand" + +// RandShuffle pseudo-randomizes the order of addresses. +var RandShuffle = rand.Shuffle diff --git a/go-controller/vendor/google.golang.org/grpc/balancer/pickfirst/pickfirst.go b/go-controller/vendor/google.golang.org/grpc/balancer/pickfirst/pickfirst.go index 07527603f1..e069346a75 100644 --- a/go-controller/vendor/google.golang.org/grpc/balancer/pickfirst/pickfirst.go +++ b/go-controller/vendor/google.golang.org/grpc/balancer/pickfirst/pickfirst.go @@ -26,18 +26,23 @@ import ( "math/rand" "google.golang.org/grpc/balancer" + "google.golang.org/grpc/balancer/pickfirst/internal" "google.golang.org/grpc/connectivity" "google.golang.org/grpc/grpclog" - "google.golang.org/grpc/internal" + "google.golang.org/grpc/internal/envconfig" internalgrpclog "google.golang.org/grpc/internal/grpclog" "google.golang.org/grpc/internal/pretty" "google.golang.org/grpc/resolver" "google.golang.org/grpc/serviceconfig" + + _ "google.golang.org/grpc/balancer/pickfirst/pickfirstleaf" // For automatically registering the new pickfirst if required. ) func init() { + if envconfig.NewPickFirstEnabled { + return + } balancer.Register(pickfirstBuilder{}) - internal.ShuffleAddressListForTesting = func(n int, swap func(i, j int)) { rand.Shuffle(n, swap) } } var logger = grpclog.Component("pick-first-lb") @@ -50,7 +55,7 @@ const ( type pickfirstBuilder struct{} -func (pickfirstBuilder) Build(cc balancer.ClientConn, opt balancer.BuildOptions) balancer.Balancer { +func (pickfirstBuilder) Build(cc balancer.ClientConn, _ balancer.BuildOptions) balancer.Balancer { b := &pickfirstBalancer{cc: cc} b.logger = internalgrpclog.NewPrefixLogger(logger, fmt.Sprintf(logPrefix, b)) return b @@ -103,10 +108,13 @@ func (b *pickfirstBalancer) ResolverError(err error) { }) } +// Shuffler is an interface for shuffling an address list. type Shuffler interface { ShuffleAddressListForTesting(n int, swap func(i, j int)) } +// ShuffleAddressListForTesting pseudo-randomizes the order of addresses. n +// is the number of elements. swap swaps the elements with indexes i and j. func ShuffleAddressListForTesting(n int, swap func(i, j int)) { rand.Shuffle(n, swap) } func (b *pickfirstBalancer) UpdateClientConnState(state balancer.ClientConnState) error { @@ -140,7 +148,7 @@ func (b *pickfirstBalancer) UpdateClientConnState(state balancer.ClientConnState // within each endpoint. - A61 if cfg.ShuffleAddressList { endpoints = append([]resolver.Endpoint{}, endpoints...) - internal.ShuffleAddressListForTesting.(func(int, func(int, int)))(len(endpoints), func(i, j int) { endpoints[i], endpoints[j] = endpoints[j], endpoints[i] }) + internal.RandShuffle(len(endpoints), func(i, j int) { endpoints[i], endpoints[j] = endpoints[j], endpoints[i] }) } // "Flatten the list by concatenating the ordered list of addresses for each @@ -155,7 +163,7 @@ func (b *pickfirstBalancer) UpdateClientConnState(state balancer.ClientConnState // Endpoints not set, process addresses until we migrate resolver // emissions fully to Endpoints. The top channel does wrap emitted // addresses with endpoints, however some balancers such as weighted - // target do not forwarrd the corresponding correct endpoints down/split + // target do not forward the corresponding correct endpoints down/split // endpoints properly. Once all balancers correctly forward endpoints // down, can delete this else conditional. addrs = state.ResolverState.Addresses diff --git a/go-controller/vendor/google.golang.org/grpc/balancer/pickfirst/pickfirstleaf/pickfirstleaf.go b/go-controller/vendor/google.golang.org/grpc/balancer/pickfirst/pickfirstleaf/pickfirstleaf.go new file mode 100644 index 0000000000..985b6edc7f --- /dev/null +++ b/go-controller/vendor/google.golang.org/grpc/balancer/pickfirst/pickfirstleaf/pickfirstleaf.go @@ -0,0 +1,625 @@ +/* + * + * Copyright 2024 gRPC authors. + * + * 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 pickfirstleaf contains the pick_first load balancing policy which +// will be the universal leaf policy after dualstack changes are implemented. +// +// # Experimental +// +// Notice: This package is EXPERIMENTAL and may be changed or removed in a +// later release. +package pickfirstleaf + +import ( + "encoding/json" + "errors" + "fmt" + "sync" + + "google.golang.org/grpc/balancer" + "google.golang.org/grpc/balancer/pickfirst/internal" + "google.golang.org/grpc/connectivity" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/internal/envconfig" + internalgrpclog "google.golang.org/grpc/internal/grpclog" + "google.golang.org/grpc/internal/pretty" + "google.golang.org/grpc/resolver" + "google.golang.org/grpc/serviceconfig" +) + +func init() { + if envconfig.NewPickFirstEnabled { + // Register as the default pick_first balancer. + Name = "pick_first" + } + balancer.Register(pickfirstBuilder{}) +} + +var ( + logger = grpclog.Component("pick-first-leaf-lb") + // Name is the name of the pick_first_leaf balancer. + // It is changed to "pick_first" in init() if this balancer is to be + // registered as the default pickfirst. + Name = "pick_first_leaf" +) + +// TODO: change to pick-first when this becomes the default pick_first policy. +const logPrefix = "[pick-first-leaf-lb %p] " + +type pickfirstBuilder struct{} + +func (pickfirstBuilder) Build(cc balancer.ClientConn, _ balancer.BuildOptions) balancer.Balancer { + b := &pickfirstBalancer{ + cc: cc, + addressList: addressList{}, + subConns: resolver.NewAddressMap(), + state: connectivity.Connecting, + mu: sync.Mutex{}, + } + b.logger = internalgrpclog.NewPrefixLogger(logger, fmt.Sprintf(logPrefix, b)) + return b +} + +func (b pickfirstBuilder) Name() string { + return Name +} + +func (pickfirstBuilder) ParseConfig(js json.RawMessage) (serviceconfig.LoadBalancingConfig, error) { + var cfg pfConfig + if err := json.Unmarshal(js, &cfg); err != nil { + return nil, fmt.Errorf("pickfirst: unable to unmarshal LB policy config: %s, error: %v", string(js), err) + } + return cfg, nil +} + +type pfConfig struct { + serviceconfig.LoadBalancingConfig `json:"-"` + + // If set to true, instructs the LB policy to shuffle the order of the list + // of endpoints received from the name resolver before attempting to + // connect to them. + ShuffleAddressList bool `json:"shuffleAddressList"` +} + +// scData keeps track of the current state of the subConn. +// It is not safe for concurrent access. +type scData struct { + // The following fields are initialized at build time and read-only after + // that. + subConn balancer.SubConn + addr resolver.Address + + state connectivity.State + lastErr error +} + +func (b *pickfirstBalancer) newSCData(addr resolver.Address) (*scData, error) { + sd := &scData{ + state: connectivity.Idle, + addr: addr, + } + sc, err := b.cc.NewSubConn([]resolver.Address{addr}, balancer.NewSubConnOptions{ + StateListener: func(state balancer.SubConnState) { + b.updateSubConnState(sd, state) + }, + }) + if err != nil { + return nil, err + } + sd.subConn = sc + return sd, nil +} + +type pickfirstBalancer struct { + // The following fields are initialized at build time and read-only after + // that and therefore do not need to be guarded by a mutex. + logger *internalgrpclog.PrefixLogger + cc balancer.ClientConn + + // The mutex is used to ensure synchronization of updates triggered + // from the idle picker and the already serialized resolver, + // SubConn state updates. + mu sync.Mutex + state connectivity.State + // scData for active subonns mapped by address. + subConns *resolver.AddressMap + addressList addressList + firstPass bool + numTF int +} + +// ResolverError is called by the ClientConn when the name resolver produces +// an error or when pickfirst determined the resolver update to be invalid. +func (b *pickfirstBalancer) ResolverError(err error) { + b.mu.Lock() + defer b.mu.Unlock() + b.resolverErrorLocked(err) +} + +func (b *pickfirstBalancer) resolverErrorLocked(err error) { + if b.logger.V(2) { + b.logger.Infof("Received error from the name resolver: %v", err) + } + + // The picker will not change since the balancer does not currently + // report an error. If the balancer hasn't received a single good resolver + // update yet, transition to TRANSIENT_FAILURE. + if b.state != connectivity.TransientFailure && b.addressList.size() > 0 { + if b.logger.V(2) { + b.logger.Infof("Ignoring resolver error because balancer is using a previous good update.") + } + return + } + + b.cc.UpdateState(balancer.State{ + ConnectivityState: connectivity.TransientFailure, + Picker: &picker{err: fmt.Errorf("name resolver error: %v", err)}, + }) +} + +func (b *pickfirstBalancer) UpdateClientConnState(state balancer.ClientConnState) error { + b.mu.Lock() + defer b.mu.Unlock() + if len(state.ResolverState.Addresses) == 0 && len(state.ResolverState.Endpoints) == 0 { + // Cleanup state pertaining to the previous resolver state. + // Treat an empty address list like an error by calling b.ResolverError. + b.state = connectivity.TransientFailure + b.closeSubConnsLocked() + b.addressList.updateAddrs(nil) + b.resolverErrorLocked(errors.New("produced zero addresses")) + return balancer.ErrBadResolverState + } + cfg, ok := state.BalancerConfig.(pfConfig) + if state.BalancerConfig != nil && !ok { + return fmt.Errorf("pickfirst: received illegal BalancerConfig (type %T): %v: %w", state.BalancerConfig, state.BalancerConfig, balancer.ErrBadResolverState) + } + + if b.logger.V(2) { + b.logger.Infof("Received new config %s, resolver state %s", pretty.ToJSON(cfg), pretty.ToJSON(state.ResolverState)) + } + + var newAddrs []resolver.Address + if endpoints := state.ResolverState.Endpoints; len(endpoints) != 0 { + // Perform the optional shuffling described in gRFC A62. The shuffling + // will change the order of endpoints but not touch the order of the + // addresses within each endpoint. - A61 + if cfg.ShuffleAddressList { + endpoints = append([]resolver.Endpoint{}, endpoints...) + internal.RandShuffle(len(endpoints), func(i, j int) { endpoints[i], endpoints[j] = endpoints[j], endpoints[i] }) + } + + // "Flatten the list by concatenating the ordered list of addresses for + // each of the endpoints, in order." - A61 + for _, endpoint := range endpoints { + // "In the flattened list, interleave addresses from the two address + // families, as per RFC-8305 section 4." - A61 + // TODO: support the above language. + newAddrs = append(newAddrs, endpoint.Addresses...) + } + } else { + // Endpoints not set, process addresses until we migrate resolver + // emissions fully to Endpoints. The top channel does wrap emitted + // addresses with endpoints, however some balancers such as weighted + // target do not forward the corresponding correct endpoints down/split + // endpoints properly. Once all balancers correctly forward endpoints + // down, can delete this else conditional. + newAddrs = state.ResolverState.Addresses + if cfg.ShuffleAddressList { + newAddrs = append([]resolver.Address{}, newAddrs...) + internal.RandShuffle(len(endpoints), func(i, j int) { endpoints[i], endpoints[j] = endpoints[j], endpoints[i] }) + } + } + + // If an address appears in multiple endpoints or in the same endpoint + // multiple times, we keep it only once. We will create only one SubConn + // for the address because an AddressMap is used to store SubConns. + // Not de-duplicating would result in attempting to connect to the same + // SubConn multiple times in the same pass. We don't want this. + newAddrs = deDupAddresses(newAddrs) + + // Since we have a new set of addresses, we are again at first pass. + b.firstPass = true + + // If the previous ready SubConn exists in new address list, + // keep this connection and don't create new SubConns. + prevAddr := b.addressList.currentAddress() + prevAddrsCount := b.addressList.size() + b.addressList.updateAddrs(newAddrs) + if b.state == connectivity.Ready && b.addressList.seekTo(prevAddr) { + return nil + } + + b.reconcileSubConnsLocked(newAddrs) + // If it's the first resolver update or the balancer was already READY + // (but the new address list does not contain the ready SubConn) or + // CONNECTING, enter CONNECTING. + // We may be in TRANSIENT_FAILURE due to a previous empty address list, + // we should still enter CONNECTING because the sticky TF behaviour + // mentioned in A62 applies only when the TRANSIENT_FAILURE is reported + // due to connectivity failures. + if b.state == connectivity.Ready || b.state == connectivity.Connecting || prevAddrsCount == 0 { + // Start connection attempt at first address. + b.state = connectivity.Connecting + b.cc.UpdateState(balancer.State{ + ConnectivityState: connectivity.Connecting, + Picker: &picker{err: balancer.ErrNoSubConnAvailable}, + }) + b.requestConnectionLocked() + } else if b.state == connectivity.TransientFailure { + // If we're in TRANSIENT_FAILURE, we stay in TRANSIENT_FAILURE until + // we're READY. See A62. + b.requestConnectionLocked() + } + return nil +} + +// UpdateSubConnState is unused as a StateListener is always registered when +// creating SubConns. +func (b *pickfirstBalancer) UpdateSubConnState(subConn balancer.SubConn, state balancer.SubConnState) { + b.logger.Errorf("UpdateSubConnState(%v, %+v) called unexpectedly", subConn, state) +} + +func (b *pickfirstBalancer) Close() { + b.mu.Lock() + defer b.mu.Unlock() + b.closeSubConnsLocked() + b.state = connectivity.Shutdown +} + +// ExitIdle moves the balancer out of idle state. It can be called concurrently +// by the idlePicker and clientConn so access to variables should be +// synchronized. +func (b *pickfirstBalancer) ExitIdle() { + b.mu.Lock() + defer b.mu.Unlock() + if b.state == connectivity.Idle && b.addressList.currentAddress() == b.addressList.first() { + b.firstPass = true + b.requestConnectionLocked() + } +} + +func (b *pickfirstBalancer) closeSubConnsLocked() { + for _, sd := range b.subConns.Values() { + sd.(*scData).subConn.Shutdown() + } + b.subConns = resolver.NewAddressMap() +} + +// deDupAddresses ensures that each address appears only once in the slice. +func deDupAddresses(addrs []resolver.Address) []resolver.Address { + seenAddrs := resolver.NewAddressMap() + retAddrs := []resolver.Address{} + + for _, addr := range addrs { + if _, ok := seenAddrs.Get(addr); ok { + continue + } + retAddrs = append(retAddrs, addr) + } + return retAddrs +} + +// reconcileSubConnsLocked updates the active subchannels based on a new address +// list from the resolver. It does this by: +// - closing subchannels: any existing subchannels associated with addresses +// that are no longer in the updated list are shut down. +// - removing subchannels: entries for these closed subchannels are removed +// from the subchannel map. +// +// This ensures that the subchannel map accurately reflects the current set of +// addresses received from the name resolver. +func (b *pickfirstBalancer) reconcileSubConnsLocked(newAddrs []resolver.Address) { + newAddrsMap := resolver.NewAddressMap() + for _, addr := range newAddrs { + newAddrsMap.Set(addr, true) + } + + for _, oldAddr := range b.subConns.Keys() { + if _, ok := newAddrsMap.Get(oldAddr); ok { + continue + } + val, _ := b.subConns.Get(oldAddr) + val.(*scData).subConn.Shutdown() + b.subConns.Delete(oldAddr) + } +} + +// shutdownRemainingLocked shuts down remaining subConns. Called when a subConn +// becomes ready, which means that all other subConn must be shutdown. +func (b *pickfirstBalancer) shutdownRemainingLocked(selected *scData) { + for _, v := range b.subConns.Values() { + sd := v.(*scData) + if sd.subConn != selected.subConn { + sd.subConn.Shutdown() + } + } + b.subConns = resolver.NewAddressMap() + b.subConns.Set(selected.addr, selected) +} + +// requestConnectionLocked starts connecting on the subchannel corresponding to +// the current address. If no subchannel exists, one is created. If the current +// subchannel is in TransientFailure, a connection to the next address is +// attempted until a subchannel is found. +func (b *pickfirstBalancer) requestConnectionLocked() { + if !b.addressList.isValid() { + return + } + var lastErr error + for valid := true; valid; valid = b.addressList.increment() { + curAddr := b.addressList.currentAddress() + sd, ok := b.subConns.Get(curAddr) + if !ok { + var err error + // We want to assign the new scData to sd from the outer scope, + // hence we can't use := below. + sd, err = b.newSCData(curAddr) + if err != nil { + // This should never happen, unless the clientConn is being shut + // down. + if b.logger.V(2) { + b.logger.Infof("Failed to create a subConn for address %v: %v", curAddr.String(), err) + } + // Do nothing, the LB policy will be closed soon. + return + } + b.subConns.Set(curAddr, sd) + } + + scd := sd.(*scData) + switch scd.state { + case connectivity.Idle: + scd.subConn.Connect() + case connectivity.TransientFailure: + // Try the next address. + lastErr = scd.lastErr + continue + case connectivity.Ready: + // Should never happen. + b.logger.Errorf("Requesting a connection even though we have a READY SubConn") + case connectivity.Shutdown: + // Should never happen. + b.logger.Errorf("SubConn with state SHUTDOWN present in SubConns map") + case connectivity.Connecting: + // Wait for the SubConn to report success or failure. + } + return + } + // All the remaining addresses in the list are in TRANSIENT_FAILURE, end the + // first pass. + b.endFirstPassLocked(lastErr) +} + +func (b *pickfirstBalancer) updateSubConnState(sd *scData, newState balancer.SubConnState) { + b.mu.Lock() + defer b.mu.Unlock() + oldState := sd.state + sd.state = newState.ConnectivityState + // Previously relevant SubConns can still callback with state updates. + // To prevent pickers from returning these obsolete SubConns, this logic + // is included to check if the current list of active SubConns includes this + // SubConn. + if activeSD, found := b.subConns.Get(sd.addr); !found || activeSD != sd { + return + } + if newState.ConnectivityState == connectivity.Shutdown { + return + } + + if newState.ConnectivityState == connectivity.Ready { + b.shutdownRemainingLocked(sd) + if !b.addressList.seekTo(sd.addr) { + // This should not fail as we should have only one SubConn after + // entering READY. The SubConn should be present in the addressList. + b.logger.Errorf("Address %q not found address list in %v", sd.addr, b.addressList.addresses) + return + } + b.state = connectivity.Ready + b.cc.UpdateState(balancer.State{ + ConnectivityState: connectivity.Ready, + Picker: &picker{result: balancer.PickResult{SubConn: sd.subConn}}, + }) + return + } + + // If the LB policy is READY, and it receives a subchannel state change, + // it means that the READY subchannel has failed. + // A SubConn can also transition from CONNECTING directly to IDLE when + // a transport is successfully created, but the connection fails + // before the SubConn can send the notification for READY. We treat + // this as a successful connection and transition to IDLE. + if (b.state == connectivity.Ready && newState.ConnectivityState != connectivity.Ready) || (oldState == connectivity.Connecting && newState.ConnectivityState == connectivity.Idle) { + // Once a transport fails, the balancer enters IDLE and starts from + // the first address when the picker is used. + b.shutdownRemainingLocked(sd) + b.state = connectivity.Idle + b.addressList.reset() + b.cc.UpdateState(balancer.State{ + ConnectivityState: connectivity.Idle, + Picker: &idlePicker{exitIdle: sync.OnceFunc(b.ExitIdle)}, + }) + return + } + + if b.firstPass { + switch newState.ConnectivityState { + case connectivity.Connecting: + // The balancer can be in either IDLE, CONNECTING or + // TRANSIENT_FAILURE. If it's in TRANSIENT_FAILURE, stay in + // TRANSIENT_FAILURE until it's READY. See A62. + // If the balancer is already in CONNECTING, no update is needed. + if b.state == connectivity.Idle { + b.state = connectivity.Connecting + b.cc.UpdateState(balancer.State{ + ConnectivityState: connectivity.Connecting, + Picker: &picker{err: balancer.ErrNoSubConnAvailable}, + }) + } + case connectivity.TransientFailure: + sd.lastErr = newState.ConnectionError + // Since we're re-using common SubConns while handling resolver + // updates, we could receive an out of turn TRANSIENT_FAILURE from + // a pass over the previous address list. We ignore such updates. + + if curAddr := b.addressList.currentAddress(); !equalAddressIgnoringBalAttributes(&curAddr, &sd.addr) { + return + } + if b.addressList.increment() { + b.requestConnectionLocked() + return + } + // End of the first pass. + b.endFirstPassLocked(newState.ConnectionError) + } + return + } + + // We have finished the first pass, keep re-connecting failing SubConns. + switch newState.ConnectivityState { + case connectivity.TransientFailure: + b.numTF = (b.numTF + 1) % b.subConns.Len() + sd.lastErr = newState.ConnectionError + if b.numTF%b.subConns.Len() == 0 { + b.cc.UpdateState(balancer.State{ + ConnectivityState: connectivity.TransientFailure, + Picker: &picker{err: newState.ConnectionError}, + }) + } + // We don't need to request re-resolution since the SubConn already + // does that before reporting TRANSIENT_FAILURE. + // TODO: #7534 - Move re-resolution requests from SubConn into + // pick_first. + case connectivity.Idle: + sd.subConn.Connect() + } +} + +func (b *pickfirstBalancer) endFirstPassLocked(lastErr error) { + b.firstPass = false + b.numTF = 0 + b.state = connectivity.TransientFailure + + b.cc.UpdateState(balancer.State{ + ConnectivityState: connectivity.TransientFailure, + Picker: &picker{err: lastErr}, + }) + // Start re-connecting all the SubConns that are already in IDLE. + for _, v := range b.subConns.Values() { + sd := v.(*scData) + if sd.state == connectivity.Idle { + sd.subConn.Connect() + } + } +} + +type picker struct { + result balancer.PickResult + err error +} + +func (p *picker) Pick(balancer.PickInfo) (balancer.PickResult, error) { + return p.result, p.err +} + +// idlePicker is used when the SubConn is IDLE and kicks the SubConn into +// CONNECTING when Pick is called. +type idlePicker struct { + exitIdle func() +} + +func (i *idlePicker) Pick(balancer.PickInfo) (balancer.PickResult, error) { + i.exitIdle() + return balancer.PickResult{}, balancer.ErrNoSubConnAvailable +} + +// addressList manages sequentially iterating over addresses present in a list +// of endpoints. It provides a 1 dimensional view of the addresses present in +// the endpoints. +// This type is not safe for concurrent access. +type addressList struct { + addresses []resolver.Address + idx int +} + +func (al *addressList) isValid() bool { + return al.idx < len(al.addresses) +} + +func (al *addressList) size() int { + return len(al.addresses) +} + +// increment moves to the next index in the address list. +// This method returns false if it went off the list, true otherwise. +func (al *addressList) increment() bool { + if !al.isValid() { + return false + } + al.idx++ + return al.idx < len(al.addresses) +} + +// currentAddress returns the current address pointed to in the addressList. +// If the list is in an invalid state, it returns an empty address instead. +func (al *addressList) currentAddress() resolver.Address { + if !al.isValid() { + return resolver.Address{} + } + return al.addresses[al.idx] +} + +// first returns the first address in the list. If the list is empty, it returns +// an empty address instead. +func (al *addressList) first() resolver.Address { + if len(al.addresses) == 0 { + return resolver.Address{} + } + return al.addresses[0] +} + +func (al *addressList) reset() { + al.idx = 0 +} + +func (al *addressList) updateAddrs(addrs []resolver.Address) { + al.addresses = addrs + al.reset() +} + +// seekTo returns false if the needle was not found and the current index was +// left unchanged. +func (al *addressList) seekTo(needle resolver.Address) bool { + for ai, addr := range al.addresses { + if !equalAddressIgnoringBalAttributes(&addr, &needle) { + continue + } + al.idx = ai + return true + } + return false +} + +// equalAddressIgnoringBalAttributes returns true is a and b are considered +// equal. This is different from the Equal method on the resolver.Address type +// which considers all fields to determine equality. Here, we only consider +// fields that are meaningful to the SubConn. +func equalAddressIgnoringBalAttributes(a, b *resolver.Address) bool { + return a.Addr == b.Addr && a.ServerName == b.ServerName && + a.Attributes.Equal(b.Attributes) && + a.Metadata == b.Metadata +} diff --git a/go-controller/vendor/google.golang.org/grpc/balancer_wrapper.go b/go-controller/vendor/google.golang.org/grpc/balancer_wrapper.go index 4161fdf47a..2a4f2878ae 100644 --- a/go-controller/vendor/google.golang.org/grpc/balancer_wrapper.go +++ b/go-controller/vendor/google.golang.org/grpc/balancer_wrapper.go @@ -24,13 +24,18 @@ import ( "sync" "google.golang.org/grpc/balancer" + "google.golang.org/grpc/codes" "google.golang.org/grpc/connectivity" + "google.golang.org/grpc/internal" "google.golang.org/grpc/internal/balancer/gracefulswitch" "google.golang.org/grpc/internal/channelz" "google.golang.org/grpc/internal/grpcsync" "google.golang.org/grpc/resolver" + "google.golang.org/grpc/status" ) +var setConnectedAddress = internal.SetConnectedAddress.(func(*balancer.SubConnState, resolver.Address)) + // ccBalancerWrapper sits between the ClientConn and the Balancer. // // ccBalancerWrapper implements methods corresponding to the ones on the @@ -79,6 +84,7 @@ func newCCBalancerWrapper(cc *ClientConn) *ccBalancerWrapper { CustomUserAgent: cc.dopts.copts.UserAgent, ChannelzParent: cc.channelz, Target: cc.parsedTarget, + MetricsRecorder: cc.metricsRecorderList, }, serializer: grpcsync.NewCallbackSerializer(ctx), serializerCancel: cancel, @@ -92,7 +98,7 @@ func newCCBalancerWrapper(cc *ClientConn) *ccBalancerWrapper { // it is safe to call into the balancer here. func (ccb *ccBalancerWrapper) updateClientConnState(ccs *balancer.ClientConnState) error { errCh := make(chan error) - ok := ccb.serializer.Schedule(func(ctx context.Context) { + uccs := func(ctx context.Context) { defer close(errCh) if ctx.Err() != nil || ccb.balancer == nil { return @@ -107,17 +113,23 @@ func (ccb *ccBalancerWrapper) updateClientConnState(ccs *balancer.ClientConnStat logger.Infof("error from balancer.UpdateClientConnState: %v", err) } errCh <- err - }) - if !ok { - return nil } + onFailure := func() { close(errCh) } + + // UpdateClientConnState can race with Close, and when the latter wins, the + // serializer is closed, and the attempt to schedule the callback will fail. + // It is acceptable to ignore this failure. But since we want to handle the + // state update in a blocking fashion (when we successfully schedule the + // callback), we have to use the ScheduleOr method and not the MaybeSchedule + // method on the serializer. + ccb.serializer.ScheduleOr(uccs, onFailure) return <-errCh } // resolverError is invoked by grpc to push a resolver error to the underlying // balancer. The call to the balancer is executed from the serializer. func (ccb *ccBalancerWrapper) resolverError(err error) { - ccb.serializer.Schedule(func(ctx context.Context) { + ccb.serializer.TrySchedule(func(ctx context.Context) { if ctx.Err() != nil || ccb.balancer == nil { return } @@ -133,7 +145,7 @@ func (ccb *ccBalancerWrapper) close() { ccb.closed = true ccb.mu.Unlock() channelz.Info(logger, ccb.cc.channelz, "ccBalancerWrapper: closing") - ccb.serializer.Schedule(func(context.Context) { + ccb.serializer.TrySchedule(func(context.Context) { if ccb.balancer == nil { return } @@ -145,7 +157,7 @@ func (ccb *ccBalancerWrapper) close() { // exitIdle invokes the balancer's exitIdle method in the serializer. func (ccb *ccBalancerWrapper) exitIdle() { - ccb.serializer.Schedule(func(ctx context.Context) { + ccb.serializer.TrySchedule(func(ctx context.Context) { if ctx.Err() != nil || ccb.balancer == nil { return } @@ -182,7 +194,7 @@ func (ccb *ccBalancerWrapper) NewSubConn(addrs []resolver.Address, opts balancer return acbw, nil } -func (ccb *ccBalancerWrapper) RemoveSubConn(sc balancer.SubConn) { +func (ccb *ccBalancerWrapper) RemoveSubConn(balancer.SubConn) { // The graceful switch balancer will never call this. logger.Errorf("ccb RemoveSubConn(%v) called unexpectedly, sc") } @@ -246,21 +258,28 @@ type acBalancerWrapper struct { ccb *ccBalancerWrapper // read-only stateListener func(balancer.SubConnState) - mu sync.Mutex - producers map[balancer.ProducerBuilder]*refCountedProducer + producersMu sync.Mutex + producers map[balancer.ProducerBuilder]*refCountedProducer } // updateState is invoked by grpc to push a subConn state update to the // underlying balancer. -func (acbw *acBalancerWrapper) updateState(s connectivity.State, err error) { - acbw.ccb.serializer.Schedule(func(ctx context.Context) { +func (acbw *acBalancerWrapper) updateState(s connectivity.State, curAddr resolver.Address, err error) { + acbw.ccb.serializer.TrySchedule(func(ctx context.Context) { if ctx.Err() != nil || acbw.ccb.balancer == nil { return } + // Invalidate all producers on any state change. + acbw.closeProducers() + // Even though it is optional for balancers, gracefulswitch ensures // opts.StateListener is set, so this cannot ever be nil. // TODO: delete this comment when UpdateSubConnState is removed. - acbw.stateListener(balancer.SubConnState{ConnectivityState: s, ConnectionError: err}) + scs := balancer.SubConnState{ConnectivityState: s, ConnectionError: err} + if s == connectivity.Ready { + setConnectedAddress(&scs, curAddr) + } + acbw.stateListener(scs) }) } @@ -277,6 +296,7 @@ func (acbw *acBalancerWrapper) Connect() { } func (acbw *acBalancerWrapper) Shutdown() { + acbw.closeProducers() acbw.ccb.cc.removeAddrConn(acbw.ac, errConnDrain) } @@ -284,9 +304,10 @@ func (acbw *acBalancerWrapper) Shutdown() { // ready, blocks until it is or ctx expires. Returns an error when the context // expires or the addrConn is shut down. func (acbw *acBalancerWrapper) NewStream(ctx context.Context, desc *StreamDesc, method string, opts ...CallOption) (ClientStream, error) { - transport, err := acbw.ac.getTransport(ctx) - if err != nil { - return nil, err + transport := acbw.ac.getReadyTransport() + if transport == nil { + return nil, status.Errorf(codes.Unavailable, "SubConn state is not Ready") + } return newNonRetryClientStream(ctx, desc, method, transport, acbw.ac, opts...) } @@ -311,15 +332,15 @@ type refCountedProducer struct { } func (acbw *acBalancerWrapper) GetOrBuildProducer(pb balancer.ProducerBuilder) (balancer.Producer, func()) { - acbw.mu.Lock() - defer acbw.mu.Unlock() + acbw.producersMu.Lock() + defer acbw.producersMu.Unlock() // Look up existing producer from this builder. pData := acbw.producers[pb] if pData == nil { // Not found; create a new one and add it to the producers map. - p, close := pb.Build(acbw) - pData = &refCountedProducer{producer: p, close: close} + p, closeFn := pb.Build(acbw) + pData = &refCountedProducer{producer: p, close: closeFn} acbw.producers[pb] = pData } // Account for this new reference. @@ -329,13 +350,26 @@ func (acbw *acBalancerWrapper) GetOrBuildProducer(pb balancer.ProducerBuilder) ( // and delete the refCountedProducer from the map if the total reference // count goes to zero. unref := func() { - acbw.mu.Lock() + acbw.producersMu.Lock() + // If closeProducers has already closed this producer instance, refs is + // set to 0, so the check after decrementing will never pass, and the + // producer will not be double-closed. pData.refs-- if pData.refs == 0 { defer pData.close() // Run outside the acbw mutex delete(acbw.producers, pb) } - acbw.mu.Unlock() + acbw.producersMu.Unlock() } return pData.producer, grpcsync.OnceFunc(unref) } + +func (acbw *acBalancerWrapper) closeProducers() { + acbw.producersMu.Lock() + defer acbw.producersMu.Unlock() + for pb, pData := range acbw.producers { + pData.refs = 0 + pData.close() + delete(acbw.producers, pb) + } +} diff --git a/go-controller/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go b/go-controller/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go index 63c639e4fe..55bffaa77e 100644 --- a/go-controller/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go +++ b/go-controller/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go @@ -18,8 +18,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.1 -// protoc v4.25.2 +// protoc-gen-go v1.34.2 +// protoc v5.27.1 // source: grpc/binlog/v1/binarylog.proto package grpc_binarylog_v1 @@ -1015,7 +1015,7 @@ func file_grpc_binlog_v1_binarylog_proto_rawDescGZIP() []byte { var file_grpc_binlog_v1_binarylog_proto_enumTypes = make([]protoimpl.EnumInfo, 3) var file_grpc_binlog_v1_binarylog_proto_msgTypes = make([]protoimpl.MessageInfo, 8) -var file_grpc_binlog_v1_binarylog_proto_goTypes = []interface{}{ +var file_grpc_binlog_v1_binarylog_proto_goTypes = []any{ (GrpcLogEntry_EventType)(0), // 0: grpc.binarylog.v1.GrpcLogEntry.EventType (GrpcLogEntry_Logger)(0), // 1: grpc.binarylog.v1.GrpcLogEntry.Logger (Address_Type)(0), // 2: grpc.binarylog.v1.Address.Type @@ -1058,7 +1058,7 @@ func file_grpc_binlog_v1_binarylog_proto_init() { return } if !protoimpl.UnsafeEnabled { - file_grpc_binlog_v1_binarylog_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_grpc_binlog_v1_binarylog_proto_msgTypes[0].Exporter = func(v any, i int) any { switch v := v.(*GrpcLogEntry); i { case 0: return &v.state @@ -1070,7 +1070,7 @@ func file_grpc_binlog_v1_binarylog_proto_init() { return nil } } - file_grpc_binlog_v1_binarylog_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_grpc_binlog_v1_binarylog_proto_msgTypes[1].Exporter = func(v any, i int) any { switch v := v.(*ClientHeader); i { case 0: return &v.state @@ -1082,7 +1082,7 @@ func file_grpc_binlog_v1_binarylog_proto_init() { return nil } } - file_grpc_binlog_v1_binarylog_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + file_grpc_binlog_v1_binarylog_proto_msgTypes[2].Exporter = func(v any, i int) any { switch v := v.(*ServerHeader); i { case 0: return &v.state @@ -1094,7 +1094,7 @@ func file_grpc_binlog_v1_binarylog_proto_init() { return nil } } - file_grpc_binlog_v1_binarylog_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + file_grpc_binlog_v1_binarylog_proto_msgTypes[3].Exporter = func(v any, i int) any { switch v := v.(*Trailer); i { case 0: return &v.state @@ -1106,7 +1106,7 @@ func file_grpc_binlog_v1_binarylog_proto_init() { return nil } } - file_grpc_binlog_v1_binarylog_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + file_grpc_binlog_v1_binarylog_proto_msgTypes[4].Exporter = func(v any, i int) any { switch v := v.(*Message); i { case 0: return &v.state @@ -1118,7 +1118,7 @@ func file_grpc_binlog_v1_binarylog_proto_init() { return nil } } - file_grpc_binlog_v1_binarylog_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + file_grpc_binlog_v1_binarylog_proto_msgTypes[5].Exporter = func(v any, i int) any { switch v := v.(*Metadata); i { case 0: return &v.state @@ -1130,7 +1130,7 @@ func file_grpc_binlog_v1_binarylog_proto_init() { return nil } } - file_grpc_binlog_v1_binarylog_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + file_grpc_binlog_v1_binarylog_proto_msgTypes[6].Exporter = func(v any, i int) any { switch v := v.(*MetadataEntry); i { case 0: return &v.state @@ -1142,7 +1142,7 @@ func file_grpc_binlog_v1_binarylog_proto_init() { return nil } } - file_grpc_binlog_v1_binarylog_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + file_grpc_binlog_v1_binarylog_proto_msgTypes[7].Exporter = func(v any, i int) any { switch v := v.(*Address); i { case 0: return &v.state @@ -1155,7 +1155,7 @@ func file_grpc_binlog_v1_binarylog_proto_init() { } } } - file_grpc_binlog_v1_binarylog_proto_msgTypes[0].OneofWrappers = []interface{}{ + file_grpc_binlog_v1_binarylog_proto_msgTypes[0].OneofWrappers = []any{ (*GrpcLogEntry_ClientHeader)(nil), (*GrpcLogEntry_ServerHeader)(nil), (*GrpcLogEntry_Message)(nil), diff --git a/go-controller/vendor/google.golang.org/grpc/clientconn.go b/go-controller/vendor/google.golang.org/grpc/clientconn.go index 423be7b43b..19763f8edd 100644 --- a/go-controller/vendor/google.golang.org/grpc/clientconn.go +++ b/go-controller/vendor/google.golang.org/grpc/clientconn.go @@ -24,6 +24,7 @@ import ( "fmt" "math" "net/url" + "slices" "strings" "sync" "sync/atomic" @@ -39,6 +40,7 @@ import ( "google.golang.org/grpc/internal/grpcsync" "google.golang.org/grpc/internal/idle" iresolver "google.golang.org/grpc/internal/resolver" + "google.golang.org/grpc/internal/stats" "google.golang.org/grpc/internal/transport" "google.golang.org/grpc/keepalive" "google.golang.org/grpc/resolver" @@ -194,8 +196,11 @@ func NewClient(target string, opts ...DialOption) (conn *ClientConn, err error) cc.csMgr = newConnectivityStateManager(cc.ctx, cc.channelz) cc.pickerWrapper = newPickerWrapper(cc.dopts.copts.StatsHandlers) + cc.metricsRecorderList = stats.NewMetricsRecorderList(cc.dopts.copts.StatsHandlers) + cc.initIdleStateLocked() // Safe to call without the lock, since nothing else has a reference to cc. cc.idlenessMgr = idle.NewManager((*idler)(cc), cc.dopts.idleTimeout) + return cc, nil } @@ -590,13 +595,14 @@ type ClientConn struct { cancel context.CancelFunc // Cancelled on close. // The following are initialized at dial time, and are read-only after that. - target string // User's dial target. - parsedTarget resolver.Target // See initParsedTargetAndResolverBuilder(). - authority string // See initAuthority(). - dopts dialOptions // Default and user specified dial options. - channelz *channelz.Channel // Channelz object. - resolverBuilder resolver.Builder // See initParsedTargetAndResolverBuilder(). - idlenessMgr *idle.Manager + target string // User's dial target. + parsedTarget resolver.Target // See initParsedTargetAndResolverBuilder(). + authority string // See initAuthority(). + dopts dialOptions // Default and user specified dial options. + channelz *channelz.Channel // Channelz object. + resolverBuilder resolver.Builder // See initParsedTargetAndResolverBuilder(). + idlenessMgr *idle.Manager + metricsRecorderList *stats.MetricsRecorderList // The following provide their own synchronization, and therefore don't // require cc.mu to be held to access them. @@ -626,11 +632,6 @@ type ClientConn struct { // WaitForStateChange waits until the connectivity.State of ClientConn changes from sourceState or // ctx expires. A true value is returned in former case and false in latter. -// -// # Experimental -// -// Notice: This API is EXPERIMENTAL and may be changed or removed in a -// later release. func (cc *ClientConn) WaitForStateChange(ctx context.Context, sourceState connectivity.State) bool { ch := cc.csMgr.getNotifyChan() if cc.csMgr.getState() != sourceState { @@ -645,11 +646,6 @@ func (cc *ClientConn) WaitForStateChange(ctx context.Context, sourceState connec } // GetState returns the connectivity.State of ClientConn. -// -// # Experimental -// -// Notice: This API is EXPERIMENTAL and may be changed or removed in a later -// release. func (cc *ClientConn) GetState() connectivity.State { return cc.csMgr.getState() } @@ -812,17 +808,11 @@ func (cc *ClientConn) applyFailingLBLocked(sc *serviceconfig.ParseResult) { cc.csMgr.updateState(connectivity.TransientFailure) } -// Makes a copy of the input addresses slice and clears out the balancer -// attributes field. Addresses are passed during subconn creation and address -// update operations. In both cases, we will clear the balancer attributes by -// calling this function, and therefore we will be able to use the Equal method -// provided by the resolver.Address type for comparison. -func copyAddressesWithoutBalancerAttributes(in []resolver.Address) []resolver.Address { +// Makes a copy of the input addresses slice. Addresses are passed during +// subconn creation and address update operations. +func copyAddresses(in []resolver.Address) []resolver.Address { out := make([]resolver.Address, len(in)) - for i := range in { - out[i] = in[i] - out[i].BalancerAttributes = nil - } + copy(out, in) return out } @@ -837,12 +827,11 @@ func (cc *ClientConn) newAddrConnLocked(addrs []resolver.Address, opts balancer. ac := &addrConn{ state: connectivity.Idle, cc: cc, - addrs: copyAddressesWithoutBalancerAttributes(addrs), + addrs: copyAddresses(addrs), scopts: opts, dopts: cc.dopts, channelz: channelz.RegisterSubChannel(cc.channelz, ""), resetBackoff: make(chan struct{}), - stateChan: make(chan struct{}), } ac.ctx, ac.cancel = context.WithCancel(cc.ctx) // Start with our address set to the first address; this may be updated if @@ -918,28 +907,29 @@ func (ac *addrConn) connect() error { ac.mu.Unlock() return nil } - ac.mu.Unlock() - ac.resetTransport() + ac.resetTransportAndUnlock() return nil } -func equalAddresses(a, b []resolver.Address) bool { - if len(a) != len(b) { - return false - } - for i, v := range a { - if !v.Equal(b[i]) { - return false - } - } - return true +// equalAddressIgnoringBalAttributes returns true is a and b are considered equal. +// This is different from the Equal method on the resolver.Address type which +// considers all fields to determine equality. Here, we only consider fields +// that are meaningful to the subConn. +func equalAddressIgnoringBalAttributes(a, b *resolver.Address) bool { + return a.Addr == b.Addr && a.ServerName == b.ServerName && + a.Attributes.Equal(b.Attributes) && + a.Metadata == b.Metadata +} + +func equalAddressesIgnoringBalAttributes(a, b []resolver.Address) bool { + return slices.EqualFunc(a, b, func(a, b resolver.Address) bool { return equalAddressIgnoringBalAttributes(&a, &b) }) } // updateAddrs updates ac.addrs with the new addresses list and handles active // connections or connection attempts. func (ac *addrConn) updateAddrs(addrs []resolver.Address) { - addrs = copyAddressesWithoutBalancerAttributes(addrs) + addrs = copyAddresses(addrs) limit := len(addrs) if limit > 5 { limit = 5 @@ -947,7 +937,7 @@ func (ac *addrConn) updateAddrs(addrs []resolver.Address) { channelz.Infof(logger, ac.channelz, "addrConn: updateAddrs addrs (%d of %d): %v", limit, len(addrs), addrs[:limit]) ac.mu.Lock() - if equalAddresses(ac.addrs, addrs) { + if equalAddressesIgnoringBalAttributes(ac.addrs, addrs) { ac.mu.Unlock() return } @@ -966,7 +956,7 @@ func (ac *addrConn) updateAddrs(addrs []resolver.Address) { // Try to find the connected address. for _, a := range addrs { a.ServerName = ac.cc.getServerName(a) - if a.Equal(ac.curAddr) { + if equalAddressIgnoringBalAttributes(&a, &ac.curAddr) { // We are connected to a valid address, so do nothing but // update the addresses. ac.mu.Unlock() @@ -992,11 +982,9 @@ func (ac *addrConn) updateAddrs(addrs []resolver.Address) { ac.updateConnectivityState(connectivity.Idle, nil) } - ac.mu.Unlock() - // Since we were connecting/connected, we should start a new connection // attempt. - go ac.resetTransport() + go ac.resetTransportAndUnlock() } // getServerName determines the serverName to be used in the connection @@ -1152,10 +1140,15 @@ func (cc *ClientConn) Close() error { <-cc.resolverWrapper.serializer.Done() <-cc.balancerWrapper.serializer.Done() - + var wg sync.WaitGroup for ac := range conns { - ac.tearDown(ErrClientConnClosing) + wg.Add(1) + go func(ac *addrConn) { + defer wg.Done() + ac.tearDown(ErrClientConnClosing) + }(ac) } + wg.Wait() cc.addTraceEvent("deleted") // TraceEvent needs to be called before RemoveEntry, as TraceEvent may add // trace reference to the entity being deleted, and thus prevent it from being @@ -1190,8 +1183,7 @@ type addrConn struct { addrs []resolver.Address // All addresses that the resolver resolved to. // Use updateConnectivityState for updating addrConn's connectivity state. - state connectivity.State - stateChan chan struct{} // closed and recreated on every state change. + state connectivity.State backoffIdx int // Needs to be stateful for resetConnectBackoff. resetBackoff chan struct{} @@ -1204,9 +1196,6 @@ func (ac *addrConn) updateConnectivityState(s connectivity.State, lastErr error) if ac.state == s { return } - // When changing states, reset the state change channel. - close(ac.stateChan) - ac.stateChan = make(chan struct{}) ac.state = s ac.channelz.ChannelMetrics.State.Store(&s) if lastErr == nil { @@ -1214,7 +1203,7 @@ func (ac *addrConn) updateConnectivityState(s connectivity.State, lastErr error) } else { channelz.Infof(logger, ac.channelz, "Subchannel Connectivity change to %v, last error: %s", s, lastErr) } - ac.acbw.updateState(s, lastErr) + ac.acbw.updateState(s, ac.curAddr, lastErr) } // adjustParams updates parameters used to create transports upon @@ -1231,8 +1220,10 @@ func (ac *addrConn) adjustParams(r transport.GoAwayReason) { } } -func (ac *addrConn) resetTransport() { - ac.mu.Lock() +// resetTransportAndUnlock unconditionally connects the addrConn. +// +// ac.mu must be held by the caller, and this function will guarantee it is released. +func (ac *addrConn) resetTransportAndUnlock() { acCtx := ac.ctx if acCtx.Err() != nil { ac.mu.Unlock() @@ -1263,6 +1254,8 @@ func (ac *addrConn) resetTransport() { ac.mu.Unlock() if err := ac.tryAllAddrs(acCtx, addrs, connectDeadline); err != nil { + // TODO: #7534 - Move re-resolution requests into the pick_first LB policy + // to ensure one resolution request per pass instead of per subconn failure. ac.cc.resolveNow(resolver.ResolveNowOptions{}) ac.mu.Lock() if acCtx.Err() != nil { @@ -1304,7 +1297,7 @@ func (ac *addrConn) resetTransport() { ac.mu.Unlock() } -// tryAllAddrs tries to creates a connection to the addresses, and stop when at +// tryAllAddrs tries to create a connection to the addresses, and stop when at // the first successful one. It returns an error if no address was successfully // connected, or updates ac appropriately with the new transport. func (ac *addrConn) tryAllAddrs(ctx context.Context, addrs []resolver.Address, connectDeadline time.Time) error { @@ -1516,29 +1509,6 @@ func (ac *addrConn) getReadyTransport() transport.ClientTransport { return nil } -// getTransport waits until the addrconn is ready and returns the transport. -// If the context expires first, returns an appropriate status. If the -// addrConn is stopped first, returns an Unavailable status error. -func (ac *addrConn) getTransport(ctx context.Context) (transport.ClientTransport, error) { - for ctx.Err() == nil { - ac.mu.Lock() - t, state, sc := ac.transport, ac.state, ac.stateChan - ac.mu.Unlock() - if state == connectivity.Ready { - return t, nil - } - if state == connectivity.Shutdown { - return nil, status.Errorf(codes.Unavailable, "SubConn shutting down") - } - - select { - case <-ctx.Done(): - case <-sc: - } - } - return nil, status.FromContextError(ctx.Err()).Err() -} - // tearDown starts to tear down the addrConn. // // Note that tearDown doesn't remove ac from ac.cc.conns, so the addrConn struct @@ -1585,7 +1555,7 @@ func (ac *addrConn) tearDown(err error) { } else { // Hard close the transport when the channel is entering idle or is // being shutdown. In the case where the channel is being shutdown, - // closing of transports is also taken care of by cancelation of cc.ctx. + // closing of transports is also taken care of by cancellation of cc.ctx. // But in the case where the channel is entering idle, we need to // explicitly close the transports here. Instead of distinguishing // between these two cases, it is simpler to close the transport diff --git a/go-controller/vendor/google.golang.org/grpc/codec.go b/go-controller/vendor/google.golang.org/grpc/codec.go index 411e3dfd47..e840858b77 100644 --- a/go-controller/vendor/google.golang.org/grpc/codec.go +++ b/go-controller/vendor/google.golang.org/grpc/codec.go @@ -21,18 +21,73 @@ package grpc import ( "google.golang.org/grpc/encoding" _ "google.golang.org/grpc/encoding/proto" // to register the Codec for "proto" + "google.golang.org/grpc/mem" ) -// baseCodec contains the functionality of both Codec and encoding.Codec, but -// omits the name/string, which vary between the two and are not needed for -// anything besides the registry in the encoding package. +// baseCodec captures the new encoding.CodecV2 interface without the Name +// function, allowing it to be implemented by older Codec and encoding.Codec +// implementations. The omitted Name function is only needed for the register in +// the encoding package and is not part of the core functionality. type baseCodec interface { - Marshal(v any) ([]byte, error) - Unmarshal(data []byte, v any) error + Marshal(v any) (mem.BufferSlice, error) + Unmarshal(data mem.BufferSlice, v any) error +} + +// getCodec returns an encoding.CodecV2 for the codec of the given name (if +// registered). Initially checks the V2 registry with encoding.GetCodecV2 and +// returns the V2 codec if it is registered. Otherwise, it checks the V1 registry +// with encoding.GetCodec and if it is registered wraps it with newCodecV1Bridge +// to turn it into an encoding.CodecV2. Returns nil otherwise. +func getCodec(name string) encoding.CodecV2 { + if codecV1 := encoding.GetCodec(name); codecV1 != nil { + return newCodecV1Bridge(codecV1) + } + + return encoding.GetCodecV2(name) +} + +func newCodecV0Bridge(c Codec) baseCodec { + return codecV0Bridge{codec: c} +} + +func newCodecV1Bridge(c encoding.Codec) encoding.CodecV2 { + return codecV1Bridge{ + codecV0Bridge: codecV0Bridge{codec: c}, + name: c.Name(), + } +} + +var _ baseCodec = codecV0Bridge{} + +type codecV0Bridge struct { + codec interface { + Marshal(v any) ([]byte, error) + Unmarshal(data []byte, v any) error + } +} + +func (c codecV0Bridge) Marshal(v any) (mem.BufferSlice, error) { + data, err := c.codec.Marshal(v) + if err != nil { + return nil, err + } + return mem.BufferSlice{mem.NewBuffer(&data, nil)}, nil +} + +func (c codecV0Bridge) Unmarshal(data mem.BufferSlice, v any) (err error) { + return c.codec.Unmarshal(data.Materialize(), v) } -var _ baseCodec = Codec(nil) -var _ baseCodec = encoding.Codec(nil) +var _ encoding.CodecV2 = codecV1Bridge{} + +type codecV1Bridge struct { + codecV0Bridge + name string +} + +func (c codecV1Bridge) Name() string { + return c.name +} // Codec defines the interface gRPC uses to encode and decode messages. // Note that implementations of this interface must be thread safe; diff --git a/go-controller/vendor/google.golang.org/grpc/credentials/insecure/insecure.go b/go-controller/vendor/google.golang.org/grpc/credentials/insecure/insecure.go index 82bee1443b..4c805c6446 100644 --- a/go-controller/vendor/google.golang.org/grpc/credentials/insecure/insecure.go +++ b/go-controller/vendor/google.golang.org/grpc/credentials/insecure/insecure.go @@ -40,7 +40,7 @@ func NewCredentials() credentials.TransportCredentials { // NoSecurity. type insecureTC struct{} -func (insecureTC) ClientHandshake(ctx context.Context, _ string, conn net.Conn) (net.Conn, credentials.AuthInfo, error) { +func (insecureTC) ClientHandshake(_ context.Context, _ string, conn net.Conn) (net.Conn, credentials.AuthInfo, error) { return conn, info{credentials.CommonAuthInfo{SecurityLevel: credentials.NoSecurity}}, nil } diff --git a/go-controller/vendor/google.golang.org/grpc/credentials/tls.go b/go-controller/vendor/google.golang.org/grpc/credentials/tls.go index 4114358545..e163a473df 100644 --- a/go-controller/vendor/google.golang.org/grpc/credentials/tls.go +++ b/go-controller/vendor/google.golang.org/grpc/credentials/tls.go @@ -200,25 +200,40 @@ var tls12ForbiddenCipherSuites = map[uint16]struct{}{ // NewTLS uses c to construct a TransportCredentials based on TLS. func NewTLS(c *tls.Config) TransportCredentials { - tc := &tlsCreds{credinternal.CloneTLSConfig(c)} - tc.config.NextProtos = credinternal.AppendH2ToNextProtos(tc.config.NextProtos) + config := applyDefaults(c) + if config.GetConfigForClient != nil { + oldFn := config.GetConfigForClient + config.GetConfigForClient = func(hello *tls.ClientHelloInfo) (*tls.Config, error) { + cfgForClient, err := oldFn(hello) + if err != nil || cfgForClient == nil { + return cfgForClient, err + } + return applyDefaults(cfgForClient), nil + } + } + return &tlsCreds{config: config} +} + +func applyDefaults(c *tls.Config) *tls.Config { + config := credinternal.CloneTLSConfig(c) + config.NextProtos = credinternal.AppendH2ToNextProtos(config.NextProtos) // If the user did not configure a MinVersion and did not configure a // MaxVersion < 1.2, use MinVersion=1.2, which is required by // https://datatracker.ietf.org/doc/html/rfc7540#section-9.2 - if tc.config.MinVersion == 0 && (tc.config.MaxVersion == 0 || tc.config.MaxVersion >= tls.VersionTLS12) { - tc.config.MinVersion = tls.VersionTLS12 + if config.MinVersion == 0 && (config.MaxVersion == 0 || config.MaxVersion >= tls.VersionTLS12) { + config.MinVersion = tls.VersionTLS12 } // If the user did not configure CipherSuites, use all "secure" cipher // suites reported by the TLS package, but remove some explicitly forbidden // by https://datatracker.ietf.org/doc/html/rfc7540#appendix-A - if tc.config.CipherSuites == nil { + if config.CipherSuites == nil { for _, cs := range tls.CipherSuites() { if _, ok := tls12ForbiddenCipherSuites[cs.ID]; !ok { - tc.config.CipherSuites = append(tc.config.CipherSuites, cs.ID) + config.CipherSuites = append(config.CipherSuites, cs.ID) } } } - return tc + return config } // NewClientTLSFromCert constructs TLS credentials from the provided root diff --git a/go-controller/vendor/google.golang.org/grpc/credentials/tls/certprovider/pemfile/builder.go b/go-controller/vendor/google.golang.org/grpc/credentials/tls/certprovider/pemfile/builder.go index 8c15baeb59..ad4207892b 100644 --- a/go-controller/vendor/google.golang.org/grpc/credentials/tls/certprovider/pemfile/builder.go +++ b/go-controller/vendor/google.golang.org/grpc/credentials/tls/certprovider/pemfile/builder.go @@ -29,6 +29,7 @@ import ( ) const ( + // PluginName is the name of the PEM file watcher plugin. PluginName = "file_watcher" defaultRefreshInterval = 10 * time.Minute ) diff --git a/go-controller/vendor/google.golang.org/grpc/credentials/tls/certprovider/store.go b/go-controller/vendor/google.golang.org/grpc/credentials/tls/certprovider/store.go index 87528b4e23..a4b99e3d4a 100644 --- a/go-controller/vendor/google.golang.org/grpc/credentials/tls/certprovider/store.go +++ b/go-controller/vendor/google.golang.org/grpc/credentials/tls/certprovider/store.go @@ -58,7 +58,7 @@ type wrappedProvider struct { // closedProvider always returns errProviderClosed error. type closedProvider struct{} -func (c closedProvider) KeyMaterial(ctx context.Context) (*KeyMaterial, error) { +func (c closedProvider) KeyMaterial(context.Context) (*KeyMaterial, error) { return nil, errProviderClosed } diff --git a/go-controller/vendor/google.golang.org/grpc/dialoptions.go b/go-controller/vendor/google.golang.org/grpc/dialoptions.go index f5453d48a5..518692c3af 100644 --- a/go-controller/vendor/google.golang.org/grpc/dialoptions.go +++ b/go-controller/vendor/google.golang.org/grpc/dialoptions.go @@ -33,6 +33,7 @@ import ( "google.golang.org/grpc/internal/binarylog" "google.golang.org/grpc/internal/transport" "google.golang.org/grpc/keepalive" + "google.golang.org/grpc/mem" "google.golang.org/grpc/resolver" "google.golang.org/grpc/stats" ) @@ -60,7 +61,7 @@ func init() { internal.WithBinaryLogger = withBinaryLogger internal.JoinDialOptions = newJoinDialOption internal.DisableGlobalDialOptions = newDisableGlobalDialOptions - internal.WithRecvBufferPool = withRecvBufferPool + internal.WithBufferPool = withBufferPool } // dialOptions configure a Dial call. dialOptions are set by the DialOption @@ -92,7 +93,6 @@ type dialOptions struct { defaultServiceConfigRawJSON *string resolvers []resolver.Builder idleTimeout time.Duration - recvBufferPool SharedBufferPool defaultScheme string maxCallAttempts int } @@ -436,7 +436,7 @@ func WithTimeout(d time.Duration) DialOption { // option to true from the Control field. For a concrete example of how to do // this, see internal.NetDialerWithTCPKeepalive(). // -// For more information, please see [issue 23459] in the Go github repo. +// For more information, please see [issue 23459] in the Go GitHub repo. // // [issue 23459]: https://github.com/golang/go/issues/23459 func WithContextDialer(f func(context.Context, string) (net.Conn, error)) DialOption { @@ -518,6 +518,8 @@ func WithUserAgent(s string) DialOption { // WithKeepaliveParams returns a DialOption that specifies keepalive parameters // for the client transport. +// +// Keepalive is disabled by default. func WithKeepaliveParams(kp keepalive.ClientParameters) DialOption { if kp.Time < internal.KeepaliveMinPingTime { logger.Warningf("Adjusting keepalive ping interval to minimum period of %v", internal.KeepaliveMinPingTime) @@ -677,11 +679,11 @@ func defaultDialOptions() dialOptions { WriteBufferSize: defaultWriteBufSize, UseProxy: true, UserAgent: grpcUA, + BufferPool: mem.DefaultBufferPool(), }, bs: internalbackoff.DefaultExponential, healthCheckFunc: internal.HealthCheckFunc, idleTimeout: 30 * time.Minute, - recvBufferPool: nopBufferPool{}, defaultScheme: "dns", maxCallAttempts: defaultMaxCallAttempts, } @@ -758,25 +760,8 @@ func WithMaxCallAttempts(n int) DialOption { }) } -// WithRecvBufferPool returns a DialOption that configures the ClientConn -// to use the provided shared buffer pool for parsing incoming messages. Depending -// on the application's workload, this could result in reduced memory allocation. -// -// If you are unsure about how to implement a memory pool but want to utilize one, -// begin with grpc.NewSharedBufferPool. -// -// Note: The shared buffer pool feature will not be active if any of the following -// options are used: WithStatsHandler, EnableTracing, or binary logging. In such -// cases, the shared buffer pool will be ignored. -// -// Deprecated: use experimental.WithRecvBufferPool instead. Will be deleted in -// v1.60.0 or later. -func WithRecvBufferPool(bufferPool SharedBufferPool) DialOption { - return withRecvBufferPool(bufferPool) -} - -func withRecvBufferPool(bufferPool SharedBufferPool) DialOption { +func withBufferPool(bufferPool mem.BufferPool) DialOption { return newFuncDialOption(func(o *dialOptions) { - o.recvBufferPool = bufferPool + o.copts.BufferPool = bufferPool }) } diff --git a/go-controller/vendor/google.golang.org/grpc/doc.go b/go-controller/vendor/google.golang.org/grpc/doc.go index 0022859ad7..e7b532b6f8 100644 --- a/go-controller/vendor/google.golang.org/grpc/doc.go +++ b/go-controller/vendor/google.golang.org/grpc/doc.go @@ -16,7 +16,7 @@ * */ -//go:generate ./regenerate.sh +//go:generate ./scripts/regenerate.sh /* Package grpc implements an RPC system called gRPC. diff --git a/go-controller/vendor/google.golang.org/grpc/encoding/encoding.go b/go-controller/vendor/google.golang.org/grpc/encoding/encoding.go index 5ebf88d714..11d0ae142c 100644 --- a/go-controller/vendor/google.golang.org/grpc/encoding/encoding.go +++ b/go-controller/vendor/google.golang.org/grpc/encoding/encoding.go @@ -94,7 +94,7 @@ type Codec interface { Name() string } -var registeredCodecs = make(map[string]Codec) +var registeredCodecs = make(map[string]any) // RegisterCodec registers the provided Codec for use with all gRPC clients and // servers. @@ -126,5 +126,6 @@ func RegisterCodec(codec Codec) { // // The content-subtype is expected to be lowercase. func GetCodec(contentSubtype string) Codec { - return registeredCodecs[contentSubtype] + c, _ := registeredCodecs[contentSubtype].(Codec) + return c } diff --git a/go-controller/vendor/google.golang.org/grpc/encoding/encoding_v2.go b/go-controller/vendor/google.golang.org/grpc/encoding/encoding_v2.go new file mode 100644 index 0000000000..074c5e234a --- /dev/null +++ b/go-controller/vendor/google.golang.org/grpc/encoding/encoding_v2.go @@ -0,0 +1,81 @@ +/* + * + * Copyright 2024 gRPC authors. + * + * 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 encoding + +import ( + "strings" + + "google.golang.org/grpc/mem" +) + +// CodecV2 defines the interface gRPC uses to encode and decode messages. Note +// that implementations of this interface must be thread safe; a CodecV2's +// methods can be called from concurrent goroutines. +type CodecV2 interface { + // Marshal returns the wire format of v. The buffers in the returned + // [mem.BufferSlice] must have at least one reference each, which will be freed + // by gRPC when they are no longer needed. + Marshal(v any) (out mem.BufferSlice, err error) + // Unmarshal parses the wire format into v. Note that data will be freed as soon + // as this function returns. If the codec wishes to guarantee access to the data + // after this function, it must take its own reference that it frees when it is + // no longer needed. + Unmarshal(data mem.BufferSlice, v any) error + // Name returns the name of the Codec implementation. The returned string + // will be used as part of content type in transmission. The result must be + // static; the result cannot change between calls. + Name() string +} + +// RegisterCodecV2 registers the provided CodecV2 for use with all gRPC clients and +// servers. +// +// The CodecV2 will be stored and looked up by result of its Name() method, which +// should match the content-subtype of the encoding handled by the CodecV2. This +// is case-insensitive, and is stored and looked up as lowercase. If the +// result of calling Name() is an empty string, RegisterCodecV2 will panic. See +// Content-Type on +// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests for +// more details. +// +// If both a Codec and CodecV2 are registered with the same name, the CodecV2 +// will be used. +// +// NOTE: this function must only be called during initialization time (i.e. in +// an init() function), and is not thread-safe. If multiple Codecs are +// registered with the same name, the one registered last will take effect. +func RegisterCodecV2(codec CodecV2) { + if codec == nil { + panic("cannot register a nil CodecV2") + } + if codec.Name() == "" { + panic("cannot register CodecV2 with empty string result for Name()") + } + contentSubtype := strings.ToLower(codec.Name()) + registeredCodecs[contentSubtype] = codec +} + +// GetCodecV2 gets a registered CodecV2 by content-subtype, or nil if no CodecV2 is +// registered for the content-subtype. +// +// The content-subtype is expected to be lowercase. +func GetCodecV2(contentSubtype string) CodecV2 { + c, _ := registeredCodecs[contentSubtype].(CodecV2) + return c +} diff --git a/go-controller/vendor/google.golang.org/grpc/encoding/proto/proto.go b/go-controller/vendor/google.golang.org/grpc/encoding/proto/proto.go index 66d5cdf03e..ceec319dd2 100644 --- a/go-controller/vendor/google.golang.org/grpc/encoding/proto/proto.go +++ b/go-controller/vendor/google.golang.org/grpc/encoding/proto/proto.go @@ -1,6 +1,6 @@ /* * - * Copyright 2018 gRPC authors. + * Copyright 2024 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ import ( "fmt" "google.golang.org/grpc/encoding" + "google.golang.org/grpc/mem" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/protoadapt" ) @@ -32,28 +33,51 @@ import ( const Name = "proto" func init() { - encoding.RegisterCodec(codec{}) + encoding.RegisterCodecV2(&codecV2{}) } -// codec is a Codec implementation with protobuf. It is the default codec for gRPC. -type codec struct{} +// codec is a CodecV2 implementation with protobuf. It is the default codec for +// gRPC. +type codecV2 struct{} -func (codec) Marshal(v any) ([]byte, error) { +func (c *codecV2) Marshal(v any) (data mem.BufferSlice, err error) { vv := messageV2Of(v) if vv == nil { - return nil, fmt.Errorf("failed to marshal, message is %T, want proto.Message", v) + return nil, fmt.Errorf("proto: failed to marshal, message is %T, want proto.Message", v) } - return proto.Marshal(vv) + size := proto.Size(vv) + if mem.IsBelowBufferPoolingThreshold(size) { + buf, err := proto.Marshal(vv) + if err != nil { + return nil, err + } + data = append(data, mem.SliceBuffer(buf)) + } else { + pool := mem.DefaultBufferPool() + buf := pool.Get(size) + if _, err := (proto.MarshalOptions{}).MarshalAppend((*buf)[:0], vv); err != nil { + pool.Put(buf) + return nil, err + } + data = append(data, mem.NewBuffer(buf, pool)) + } + + return data, nil } -func (codec) Unmarshal(data []byte, v any) error { +func (c *codecV2) Unmarshal(data mem.BufferSlice, v any) (err error) { vv := messageV2Of(v) if vv == nil { return fmt.Errorf("failed to unmarshal, message is %T, want proto.Message", v) } - return proto.Unmarshal(data, vv) + buf := data.MaterializeToBuffer(mem.DefaultBufferPool()) + defer buf.Free() + // TODO: Upgrade proto.Unmarshal to support mem.BufferSlice. Right now, it's not + // really possible without a major overhaul of the proto package, but the + // vtprotobuf library may be able to support this. + return proto.Unmarshal(buf.ReadOnlyData(), vv) } func messageV2Of(v any) proto.Message { @@ -67,6 +91,6 @@ func messageV2Of(v any) proto.Message { return nil } -func (codec) Name() string { +func (c *codecV2) Name() string { return Name } diff --git a/go-controller/vendor/google.golang.org/grpc/experimental/stats/metricregistry.go b/go-controller/vendor/google.golang.org/grpc/experimental/stats/metricregistry.go new file mode 100644 index 0000000000..1d827dd5d9 --- /dev/null +++ b/go-controller/vendor/google.golang.org/grpc/experimental/stats/metricregistry.go @@ -0,0 +1,269 @@ +/* + * + * Copyright 2024 gRPC authors. + * + * 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 stats + +import ( + "maps" + + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/internal" +) + +func init() { + internal.SnapshotMetricRegistryForTesting = snapshotMetricsRegistryForTesting +} + +var logger = grpclog.Component("metrics-registry") + +// DefaultMetrics are the default metrics registered through global metrics +// registry. This is written to at initialization time only, and is read only +// after initialization. +var DefaultMetrics = NewMetrics() + +// MetricDescriptor is the data for a registered metric. +type MetricDescriptor struct { + // The name of this metric. This name must be unique across the whole binary + // (including any per call metrics). See + // https://github.com/grpc/proposal/blob/master/A79-non-per-call-metrics-architecture.md#metric-instrument-naming-conventions + // for metric naming conventions. + Name Metric + // The description of this metric. + Description string + // The unit (e.g. entries, seconds) of this metric. + Unit string + // The required label keys for this metric. These are intended to + // metrics emitted from a stats handler. + Labels []string + // The optional label keys for this metric. These are intended to attached + // to metrics emitted from a stats handler if configured. + OptionalLabels []string + // Whether this metric is on by default. + Default bool + // The type of metric. This is set by the metric registry, and not intended + // to be set by a component registering a metric. + Type MetricType + // Bounds are the bounds of this metric. This only applies to histogram + // metrics. If unset or set with length 0, stats handlers will fall back to + // default bounds. + Bounds []float64 +} + +// MetricType is the type of metric. +type MetricType int + +// Type of metric supported by this instrument registry. +const ( + MetricTypeIntCount MetricType = iota + MetricTypeFloatCount + MetricTypeIntHisto + MetricTypeFloatHisto + MetricTypeIntGauge +) + +// Int64CountHandle is a typed handle for a int count metric. This handle +// is passed at the recording point in order to know which metric to record +// on. +type Int64CountHandle MetricDescriptor + +// Descriptor returns the int64 count handle typecast to a pointer to a +// MetricDescriptor. +func (h *Int64CountHandle) Descriptor() *MetricDescriptor { + return (*MetricDescriptor)(h) +} + +// Record records the int64 count value on the metrics recorder provided. +func (h *Int64CountHandle) Record(recorder MetricsRecorder, incr int64, labels ...string) { + recorder.RecordInt64Count(h, incr, labels...) +} + +// Float64CountHandle is a typed handle for a float count metric. This handle is +// passed at the recording point in order to know which metric to record on. +type Float64CountHandle MetricDescriptor + +// Descriptor returns the float64 count handle typecast to a pointer to a +// MetricDescriptor. +func (h *Float64CountHandle) Descriptor() *MetricDescriptor { + return (*MetricDescriptor)(h) +} + +// Record records the float64 count value on the metrics recorder provided. +func (h *Float64CountHandle) Record(recorder MetricsRecorder, incr float64, labels ...string) { + recorder.RecordFloat64Count(h, incr, labels...) +} + +// Int64HistoHandle is a typed handle for an int histogram metric. This handle +// is passed at the recording point in order to know which metric to record on. +type Int64HistoHandle MetricDescriptor + +// Descriptor returns the int64 histo handle typecast to a pointer to a +// MetricDescriptor. +func (h *Int64HistoHandle) Descriptor() *MetricDescriptor { + return (*MetricDescriptor)(h) +} + +// Record records the int64 histo value on the metrics recorder provided. +func (h *Int64HistoHandle) Record(recorder MetricsRecorder, incr int64, labels ...string) { + recorder.RecordInt64Histo(h, incr, labels...) +} + +// Float64HistoHandle is a typed handle for a float histogram metric. This +// handle is passed at the recording point in order to know which metric to +// record on. +type Float64HistoHandle MetricDescriptor + +// Descriptor returns the float64 histo handle typecast to a pointer to a +// MetricDescriptor. +func (h *Float64HistoHandle) Descriptor() *MetricDescriptor { + return (*MetricDescriptor)(h) +} + +// Record records the float64 histo value on the metrics recorder provided. +func (h *Float64HistoHandle) Record(recorder MetricsRecorder, incr float64, labels ...string) { + recorder.RecordFloat64Histo(h, incr, labels...) +} + +// Int64GaugeHandle is a typed handle for an int gauge metric. This handle is +// passed at the recording point in order to know which metric to record on. +type Int64GaugeHandle MetricDescriptor + +// Descriptor returns the int64 gauge handle typecast to a pointer to a +// MetricDescriptor. +func (h *Int64GaugeHandle) Descriptor() *MetricDescriptor { + return (*MetricDescriptor)(h) +} + +// Record records the int64 histo value on the metrics recorder provided. +func (h *Int64GaugeHandle) Record(recorder MetricsRecorder, incr int64, labels ...string) { + recorder.RecordInt64Gauge(h, incr, labels...) +} + +// registeredMetrics are the registered metric descriptor names. +var registeredMetrics = make(map[Metric]bool) + +// metricsRegistry contains all of the registered metrics. +// +// This is written to only at init time, and read only after that. +var metricsRegistry = make(map[Metric]*MetricDescriptor) + +// DescriptorForMetric returns the MetricDescriptor from the global registry. +// +// Returns nil if MetricDescriptor not present. +func DescriptorForMetric(metric Metric) *MetricDescriptor { + return metricsRegistry[metric] +} + +func registerMetric(name Metric, def bool) { + if registeredMetrics[name] { + logger.Fatalf("metric %v already registered", name) + } + registeredMetrics[name] = true + if def { + DefaultMetrics = DefaultMetrics.Add(name) + } +} + +// RegisterInt64Count registers the metric description onto the global registry. +// It returns a typed handle to use to recording data. +// +// NOTE: this function must only be called during initialization time (i.e. in +// an init() function), and is not thread-safe. If multiple metrics are +// registered with the same name, this function will panic. +func RegisterInt64Count(descriptor MetricDescriptor) *Int64CountHandle { + registerMetric(descriptor.Name, descriptor.Default) + descriptor.Type = MetricTypeIntCount + descPtr := &descriptor + metricsRegistry[descriptor.Name] = descPtr + return (*Int64CountHandle)(descPtr) +} + +// RegisterFloat64Count registers the metric description onto the global +// registry. It returns a typed handle to use to recording data. +// +// NOTE: this function must only be called during initialization time (i.e. in +// an init() function), and is not thread-safe. If multiple metrics are +// registered with the same name, this function will panic. +func RegisterFloat64Count(descriptor MetricDescriptor) *Float64CountHandle { + registerMetric(descriptor.Name, descriptor.Default) + descriptor.Type = MetricTypeFloatCount + descPtr := &descriptor + metricsRegistry[descriptor.Name] = descPtr + return (*Float64CountHandle)(descPtr) +} + +// RegisterInt64Histo registers the metric description onto the global registry. +// It returns a typed handle to use to recording data. +// +// NOTE: this function must only be called during initialization time (i.e. in +// an init() function), and is not thread-safe. If multiple metrics are +// registered with the same name, this function will panic. +func RegisterInt64Histo(descriptor MetricDescriptor) *Int64HistoHandle { + registerMetric(descriptor.Name, descriptor.Default) + descriptor.Type = MetricTypeIntHisto + descPtr := &descriptor + metricsRegistry[descriptor.Name] = descPtr + return (*Int64HistoHandle)(descPtr) +} + +// RegisterFloat64Histo registers the metric description onto the global +// registry. It returns a typed handle to use to recording data. +// +// NOTE: this function must only be called during initialization time (i.e. in +// an init() function), and is not thread-safe. If multiple metrics are +// registered with the same name, this function will panic. +func RegisterFloat64Histo(descriptor MetricDescriptor) *Float64HistoHandle { + registerMetric(descriptor.Name, descriptor.Default) + descriptor.Type = MetricTypeFloatHisto + descPtr := &descriptor + metricsRegistry[descriptor.Name] = descPtr + return (*Float64HistoHandle)(descPtr) +} + +// RegisterInt64Gauge registers the metric description onto the global registry. +// It returns a typed handle to use to recording data. +// +// NOTE: this function must only be called during initialization time (i.e. in +// an init() function), and is not thread-safe. If multiple metrics are +// registered with the same name, this function will panic. +func RegisterInt64Gauge(descriptor MetricDescriptor) *Int64GaugeHandle { + registerMetric(descriptor.Name, descriptor.Default) + descriptor.Type = MetricTypeIntGauge + descPtr := &descriptor + metricsRegistry[descriptor.Name] = descPtr + return (*Int64GaugeHandle)(descPtr) +} + +// snapshotMetricsRegistryForTesting snapshots the global data of the metrics +// registry. Returns a cleanup function that sets the metrics registry to its +// original state. +func snapshotMetricsRegistryForTesting() func() { + oldDefaultMetrics := DefaultMetrics + oldRegisteredMetrics := registeredMetrics + oldMetricsRegistry := metricsRegistry + + registeredMetrics = make(map[Metric]bool) + metricsRegistry = make(map[Metric]*MetricDescriptor) + maps.Copy(registeredMetrics, registeredMetrics) + maps.Copy(metricsRegistry, metricsRegistry) + + return func() { + DefaultMetrics = oldDefaultMetrics + registeredMetrics = oldRegisteredMetrics + metricsRegistry = oldMetricsRegistry + } +} diff --git a/go-controller/vendor/google.golang.org/grpc/experimental/stats/metrics.go b/go-controller/vendor/google.golang.org/grpc/experimental/stats/metrics.go new file mode 100644 index 0000000000..3221f7a633 --- /dev/null +++ b/go-controller/vendor/google.golang.org/grpc/experimental/stats/metrics.go @@ -0,0 +1,114 @@ +/* + * + * Copyright 2024 gRPC authors. + * + * 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 stats contains experimental metrics/stats API's. +package stats + +import "maps" + +// MetricsRecorder records on metrics derived from metric registry. +type MetricsRecorder interface { + // RecordInt64Count records the measurement alongside labels on the int + // count associated with the provided handle. + RecordInt64Count(handle *Int64CountHandle, incr int64, labels ...string) + // RecordFloat64Count records the measurement alongside labels on the float + // count associated with the provided handle. + RecordFloat64Count(handle *Float64CountHandle, incr float64, labels ...string) + // RecordInt64Histo records the measurement alongside labels on the int + // histo associated with the provided handle. + RecordInt64Histo(handle *Int64HistoHandle, incr int64, labels ...string) + // RecordFloat64Histo records the measurement alongside labels on the float + // histo associated with the provided handle. + RecordFloat64Histo(handle *Float64HistoHandle, incr float64, labels ...string) + // RecordInt64Gauge records the measurement alongside labels on the int + // gauge associated with the provided handle. + RecordInt64Gauge(handle *Int64GaugeHandle, incr int64, labels ...string) +} + +// Metric is an identifier for a metric. +type Metric string + +// Metrics is a set of metrics to record. Once created, Metrics is immutable, +// however Add and Remove can make copies with specific metrics added or +// removed, respectively. +// +// Do not construct directly; use NewMetrics instead. +type Metrics struct { + // metrics are the set of metrics to initialize. + metrics map[Metric]bool +} + +// NewMetrics returns a Metrics containing Metrics. +func NewMetrics(metrics ...Metric) *Metrics { + newMetrics := make(map[Metric]bool) + for _, metric := range metrics { + newMetrics[metric] = true + } + return &Metrics{ + metrics: newMetrics, + } +} + +// Metrics returns the metrics set. The returned map is read-only and must not +// be modified. +func (m *Metrics) Metrics() map[Metric]bool { + return m.metrics +} + +// Add adds the metrics to the metrics set and returns a new copy with the +// additional metrics. +func (m *Metrics) Add(metrics ...Metric) *Metrics { + newMetrics := make(map[Metric]bool) + for metric := range m.metrics { + newMetrics[metric] = true + } + + for _, metric := range metrics { + newMetrics[metric] = true + } + return &Metrics{ + metrics: newMetrics, + } +} + +// Join joins the metrics passed in with the metrics set, and returns a new copy +// with the merged metrics. +func (m *Metrics) Join(metrics *Metrics) *Metrics { + newMetrics := make(map[Metric]bool) + maps.Copy(newMetrics, m.metrics) + maps.Copy(newMetrics, metrics.metrics) + return &Metrics{ + metrics: newMetrics, + } +} + +// Remove removes the metrics from the metrics set and returns a new copy with +// the metrics removed. +func (m *Metrics) Remove(metrics ...Metric) *Metrics { + newMetrics := make(map[Metric]bool) + for metric := range m.metrics { + newMetrics[metric] = true + } + + for _, metric := range metrics { + delete(newMetrics, metric) + } + return &Metrics{ + metrics: newMetrics, + } +} diff --git a/go-controller/vendor/google.golang.org/grpc/grpclog/component.go b/go-controller/vendor/google.golang.org/grpc/grpclog/component.go index ac73c9ced2..f1ae080dcb 100644 --- a/go-controller/vendor/google.golang.org/grpc/grpclog/component.go +++ b/go-controller/vendor/google.golang.org/grpc/grpclog/component.go @@ -20,8 +20,6 @@ package grpclog import ( "fmt" - - "google.golang.org/grpc/internal/grpclog" ) // componentData records the settings for a component. @@ -33,22 +31,22 @@ var cache = map[string]*componentData{} func (c *componentData) InfoDepth(depth int, args ...any) { args = append([]any{"[" + string(c.name) + "]"}, args...) - grpclog.InfoDepth(depth+1, args...) + InfoDepth(depth+1, args...) } func (c *componentData) WarningDepth(depth int, args ...any) { args = append([]any{"[" + string(c.name) + "]"}, args...) - grpclog.WarningDepth(depth+1, args...) + WarningDepth(depth+1, args...) } func (c *componentData) ErrorDepth(depth int, args ...any) { args = append([]any{"[" + string(c.name) + "]"}, args...) - grpclog.ErrorDepth(depth+1, args...) + ErrorDepth(depth+1, args...) } func (c *componentData) FatalDepth(depth int, args ...any) { args = append([]any{"[" + string(c.name) + "]"}, args...) - grpclog.FatalDepth(depth+1, args...) + FatalDepth(depth+1, args...) } func (c *componentData) Info(args ...any) { diff --git a/go-controller/vendor/google.golang.org/grpc/grpclog/grpclog.go b/go-controller/vendor/google.golang.org/grpc/grpclog/grpclog.go index 16928c9cb9..db320105e6 100644 --- a/go-controller/vendor/google.golang.org/grpc/grpclog/grpclog.go +++ b/go-controller/vendor/google.golang.org/grpc/grpclog/grpclog.go @@ -18,18 +18,15 @@ // Package grpclog defines logging for grpc. // -// All logs in transport and grpclb packages only go to verbose level 2. -// All logs in other packages in grpc are logged in spite of the verbosity level. -// -// In the default logger, -// severity level can be set by environment variable GRPC_GO_LOG_SEVERITY_LEVEL, -// verbosity level can be set by GRPC_GO_LOG_VERBOSITY_LEVEL. -package grpclog // import "google.golang.org/grpc/grpclog" +// In the default logger, severity level can be set by environment variable +// GRPC_GO_LOG_SEVERITY_LEVEL, verbosity level can be set by +// GRPC_GO_LOG_VERBOSITY_LEVEL. +package grpclog import ( "os" - "google.golang.org/grpc/internal/grpclog" + "google.golang.org/grpc/grpclog/internal" ) func init() { @@ -38,58 +35,58 @@ func init() { // V reports whether verbosity level l is at least the requested verbose level. func V(l int) bool { - return grpclog.Logger.V(l) + return internal.LoggerV2Impl.V(l) } // Info logs to the INFO log. func Info(args ...any) { - grpclog.Logger.Info(args...) + internal.LoggerV2Impl.Info(args...) } // Infof logs to the INFO log. Arguments are handled in the manner of fmt.Printf. func Infof(format string, args ...any) { - grpclog.Logger.Infof(format, args...) + internal.LoggerV2Impl.Infof(format, args...) } // Infoln logs to the INFO log. Arguments are handled in the manner of fmt.Println. func Infoln(args ...any) { - grpclog.Logger.Infoln(args...) + internal.LoggerV2Impl.Infoln(args...) } // Warning logs to the WARNING log. func Warning(args ...any) { - grpclog.Logger.Warning(args...) + internal.LoggerV2Impl.Warning(args...) } // Warningf logs to the WARNING log. Arguments are handled in the manner of fmt.Printf. func Warningf(format string, args ...any) { - grpclog.Logger.Warningf(format, args...) + internal.LoggerV2Impl.Warningf(format, args...) } // Warningln logs to the WARNING log. Arguments are handled in the manner of fmt.Println. func Warningln(args ...any) { - grpclog.Logger.Warningln(args...) + internal.LoggerV2Impl.Warningln(args...) } // Error logs to the ERROR log. func Error(args ...any) { - grpclog.Logger.Error(args...) + internal.LoggerV2Impl.Error(args...) } // Errorf logs to the ERROR log. Arguments are handled in the manner of fmt.Printf. func Errorf(format string, args ...any) { - grpclog.Logger.Errorf(format, args...) + internal.LoggerV2Impl.Errorf(format, args...) } // Errorln logs to the ERROR log. Arguments are handled in the manner of fmt.Println. func Errorln(args ...any) { - grpclog.Logger.Errorln(args...) + internal.LoggerV2Impl.Errorln(args...) } // Fatal logs to the FATAL log. Arguments are handled in the manner of fmt.Print. // It calls os.Exit() with exit code 1. func Fatal(args ...any) { - grpclog.Logger.Fatal(args...) + internal.LoggerV2Impl.Fatal(args...) // Make sure fatal logs will exit. os.Exit(1) } @@ -97,15 +94,15 @@ func Fatal(args ...any) { // Fatalf logs to the FATAL log. Arguments are handled in the manner of fmt.Printf. // It calls os.Exit() with exit code 1. func Fatalf(format string, args ...any) { - grpclog.Logger.Fatalf(format, args...) + internal.LoggerV2Impl.Fatalf(format, args...) // Make sure fatal logs will exit. os.Exit(1) } // Fatalln logs to the FATAL log. Arguments are handled in the manner of fmt.Println. -// It calle os.Exit()) with exit code 1. +// It calls os.Exit() with exit code 1. func Fatalln(args ...any) { - grpclog.Logger.Fatalln(args...) + internal.LoggerV2Impl.Fatalln(args...) // Make sure fatal logs will exit. os.Exit(1) } @@ -114,19 +111,76 @@ func Fatalln(args ...any) { // // Deprecated: use Info. func Print(args ...any) { - grpclog.Logger.Info(args...) + internal.LoggerV2Impl.Info(args...) } // Printf prints to the logger. Arguments are handled in the manner of fmt.Printf. // // Deprecated: use Infof. func Printf(format string, args ...any) { - grpclog.Logger.Infof(format, args...) + internal.LoggerV2Impl.Infof(format, args...) } // Println prints to the logger. Arguments are handled in the manner of fmt.Println. // // Deprecated: use Infoln. func Println(args ...any) { - grpclog.Logger.Infoln(args...) + internal.LoggerV2Impl.Infoln(args...) +} + +// InfoDepth logs to the INFO log at the specified depth. +// +// # Experimental +// +// Notice: This API is EXPERIMENTAL and may be changed or removed in a +// later release. +func InfoDepth(depth int, args ...any) { + if internal.DepthLoggerV2Impl != nil { + internal.DepthLoggerV2Impl.InfoDepth(depth, args...) + } else { + internal.LoggerV2Impl.Infoln(args...) + } +} + +// WarningDepth logs to the WARNING log at the specified depth. +// +// # Experimental +// +// Notice: This API is EXPERIMENTAL and may be changed or removed in a +// later release. +func WarningDepth(depth int, args ...any) { + if internal.DepthLoggerV2Impl != nil { + internal.DepthLoggerV2Impl.WarningDepth(depth, args...) + } else { + internal.LoggerV2Impl.Warningln(args...) + } +} + +// ErrorDepth logs to the ERROR log at the specified depth. +// +// # Experimental +// +// Notice: This API is EXPERIMENTAL and may be changed or removed in a +// later release. +func ErrorDepth(depth int, args ...any) { + if internal.DepthLoggerV2Impl != nil { + internal.DepthLoggerV2Impl.ErrorDepth(depth, args...) + } else { + internal.LoggerV2Impl.Errorln(args...) + } +} + +// FatalDepth logs to the FATAL log at the specified depth. +// +// # Experimental +// +// Notice: This API is EXPERIMENTAL and may be changed or removed in a +// later release. +func FatalDepth(depth int, args ...any) { + if internal.DepthLoggerV2Impl != nil { + internal.DepthLoggerV2Impl.FatalDepth(depth, args...) + } else { + internal.LoggerV2Impl.Fatalln(args...) + } + os.Exit(1) } diff --git a/go-controller/vendor/google.golang.org/grpc/grpclog/internal/grpclog.go b/go-controller/vendor/google.golang.org/grpc/grpclog/internal/grpclog.go new file mode 100644 index 0000000000..59c03bc14c --- /dev/null +++ b/go-controller/vendor/google.golang.org/grpc/grpclog/internal/grpclog.go @@ -0,0 +1,26 @@ +/* + * + * Copyright 2024 gRPC authors. + * + * 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 internal contains functionality internal to the grpclog package. +package internal + +// LoggerV2Impl is the logger used for the non-depth log functions. +var LoggerV2Impl LoggerV2 + +// DepthLoggerV2Impl is the logger used for the depth log functions. +var DepthLoggerV2Impl DepthLoggerV2 diff --git a/go-controller/vendor/google.golang.org/grpc/grpclog/internal/logger.go b/go-controller/vendor/google.golang.org/grpc/grpclog/internal/logger.go new file mode 100644 index 0000000000..e524fdd40b --- /dev/null +++ b/go-controller/vendor/google.golang.org/grpc/grpclog/internal/logger.go @@ -0,0 +1,87 @@ +/* + * + * Copyright 2024 gRPC authors. + * + * 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 internal + +// Logger mimics golang's standard Logger as an interface. +// +// Deprecated: use LoggerV2. +type Logger interface { + Fatal(args ...any) + Fatalf(format string, args ...any) + Fatalln(args ...any) + Print(args ...any) + Printf(format string, args ...any) + Println(args ...any) +} + +// LoggerWrapper wraps Logger into a LoggerV2. +type LoggerWrapper struct { + Logger +} + +// Info logs to INFO log. Arguments are handled in the manner of fmt.Print. +func (l *LoggerWrapper) Info(args ...any) { + l.Logger.Print(args...) +} + +// Infoln logs to INFO log. Arguments are handled in the manner of fmt.Println. +func (l *LoggerWrapper) Infoln(args ...any) { + l.Logger.Println(args...) +} + +// Infof logs to INFO log. Arguments are handled in the manner of fmt.Printf. +func (l *LoggerWrapper) Infof(format string, args ...any) { + l.Logger.Printf(format, args...) +} + +// Warning logs to WARNING log. Arguments are handled in the manner of fmt.Print. +func (l *LoggerWrapper) Warning(args ...any) { + l.Logger.Print(args...) +} + +// Warningln logs to WARNING log. Arguments are handled in the manner of fmt.Println. +func (l *LoggerWrapper) Warningln(args ...any) { + l.Logger.Println(args...) +} + +// Warningf logs to WARNING log. Arguments are handled in the manner of fmt.Printf. +func (l *LoggerWrapper) Warningf(format string, args ...any) { + l.Logger.Printf(format, args...) +} + +// Error logs to ERROR log. Arguments are handled in the manner of fmt.Print. +func (l *LoggerWrapper) Error(args ...any) { + l.Logger.Print(args...) +} + +// Errorln logs to ERROR log. Arguments are handled in the manner of fmt.Println. +func (l *LoggerWrapper) Errorln(args ...any) { + l.Logger.Println(args...) +} + +// Errorf logs to ERROR log. Arguments are handled in the manner of fmt.Printf. +func (l *LoggerWrapper) Errorf(format string, args ...any) { + l.Logger.Printf(format, args...) +} + +// V reports whether verbosity level l is at least the requested verbose level. +func (*LoggerWrapper) V(int) bool { + // Returns true for all verbose level. + return true +} diff --git a/go-controller/vendor/google.golang.org/grpc/internal/grpclog/grpclog.go b/go-controller/vendor/google.golang.org/grpc/grpclog/internal/loggerv2.go similarity index 52% rename from go-controller/vendor/google.golang.org/grpc/internal/grpclog/grpclog.go rename to go-controller/vendor/google.golang.org/grpc/grpclog/internal/loggerv2.go index bfc45102ab..07df71e98a 100644 --- a/go-controller/vendor/google.golang.org/grpc/internal/grpclog/grpclog.go +++ b/go-controller/vendor/google.golang.org/grpc/grpclog/internal/loggerv2.go @@ -1,6 +1,6 @@ /* * - * Copyright 2020 gRPC authors. + * Copyright 2024 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,59 +16,17 @@ * */ -// Package grpclog (internal) defines depth logging for grpc. -package grpclog +package internal import ( + "encoding/json" + "fmt" + "io" + "log" "os" ) -// Logger is the logger used for the non-depth log functions. -var Logger LoggerV2 - -// DepthLogger is the logger used for the depth log functions. -var DepthLogger DepthLoggerV2 - -// InfoDepth logs to the INFO log at the specified depth. -func InfoDepth(depth int, args ...any) { - if DepthLogger != nil { - DepthLogger.InfoDepth(depth, args...) - } else { - Logger.Infoln(args...) - } -} - -// WarningDepth logs to the WARNING log at the specified depth. -func WarningDepth(depth int, args ...any) { - if DepthLogger != nil { - DepthLogger.WarningDepth(depth, args...) - } else { - Logger.Warningln(args...) - } -} - -// ErrorDepth logs to the ERROR log at the specified depth. -func ErrorDepth(depth int, args ...any) { - if DepthLogger != nil { - DepthLogger.ErrorDepth(depth, args...) - } else { - Logger.Errorln(args...) - } -} - -// FatalDepth logs to the FATAL log at the specified depth. -func FatalDepth(depth int, args ...any) { - if DepthLogger != nil { - DepthLogger.FatalDepth(depth, args...) - } else { - Logger.Fatalln(args...) - } - os.Exit(1) -} - // LoggerV2 does underlying logging work for grpclog. -// This is a copy of the LoggerV2 defined in the external grpclog package. It -// is defined here to avoid a circular dependency. type LoggerV2 interface { // Info logs to INFO log. Arguments are handled in the manner of fmt.Print. Info(args ...any) @@ -107,14 +65,13 @@ type LoggerV2 interface { // DepthLoggerV2 logs at a specified call frame. If a LoggerV2 also implements // DepthLoggerV2, the below functions will be called with the appropriate stack // depth set for trivial functions the logger may ignore. -// This is a copy of the DepthLoggerV2 defined in the external grpclog package. -// It is defined here to avoid a circular dependency. // // # Experimental // // Notice: This type is EXPERIMENTAL and may be changed or removed in a // later release. type DepthLoggerV2 interface { + LoggerV2 // InfoDepth logs to INFO log at the specified depth. Arguments are handled in the manner of fmt.Println. InfoDepth(depth int, args ...any) // WarningDepth logs to WARNING log at the specified depth. Arguments are handled in the manner of fmt.Println. @@ -124,3 +81,124 @@ type DepthLoggerV2 interface { // FatalDepth logs to FATAL log at the specified depth. Arguments are handled in the manner of fmt.Println. FatalDepth(depth int, args ...any) } + +const ( + // infoLog indicates Info severity. + infoLog int = iota + // warningLog indicates Warning severity. + warningLog + // errorLog indicates Error severity. + errorLog + // fatalLog indicates Fatal severity. + fatalLog +) + +// severityName contains the string representation of each severity. +var severityName = []string{ + infoLog: "INFO", + warningLog: "WARNING", + errorLog: "ERROR", + fatalLog: "FATAL", +} + +// loggerT is the default logger used by grpclog. +type loggerT struct { + m []*log.Logger + v int + jsonFormat bool +} + +func (g *loggerT) output(severity int, s string) { + sevStr := severityName[severity] + if !g.jsonFormat { + g.m[severity].Output(2, fmt.Sprintf("%v: %v", sevStr, s)) + return + } + // TODO: we can also include the logging component, but that needs more + // (API) changes. + b, _ := json.Marshal(map[string]string{ + "severity": sevStr, + "message": s, + }) + g.m[severity].Output(2, string(b)) +} + +func (g *loggerT) Info(args ...any) { + g.output(infoLog, fmt.Sprint(args...)) +} + +func (g *loggerT) Infoln(args ...any) { + g.output(infoLog, fmt.Sprintln(args...)) +} + +func (g *loggerT) Infof(format string, args ...any) { + g.output(infoLog, fmt.Sprintf(format, args...)) +} + +func (g *loggerT) Warning(args ...any) { + g.output(warningLog, fmt.Sprint(args...)) +} + +func (g *loggerT) Warningln(args ...any) { + g.output(warningLog, fmt.Sprintln(args...)) +} + +func (g *loggerT) Warningf(format string, args ...any) { + g.output(warningLog, fmt.Sprintf(format, args...)) +} + +func (g *loggerT) Error(args ...any) { + g.output(errorLog, fmt.Sprint(args...)) +} + +func (g *loggerT) Errorln(args ...any) { + g.output(errorLog, fmt.Sprintln(args...)) +} + +func (g *loggerT) Errorf(format string, args ...any) { + g.output(errorLog, fmt.Sprintf(format, args...)) +} + +func (g *loggerT) Fatal(args ...any) { + g.output(fatalLog, fmt.Sprint(args...)) + os.Exit(1) +} + +func (g *loggerT) Fatalln(args ...any) { + g.output(fatalLog, fmt.Sprintln(args...)) + os.Exit(1) +} + +func (g *loggerT) Fatalf(format string, args ...any) { + g.output(fatalLog, fmt.Sprintf(format, args...)) + os.Exit(1) +} + +func (g *loggerT) V(l int) bool { + return l <= g.v +} + +// LoggerV2Config configures the LoggerV2 implementation. +type LoggerV2Config struct { + // Verbosity sets the verbosity level of the logger. + Verbosity int + // FormatJSON controls whether the logger should output logs in JSON format. + FormatJSON bool +} + +// NewLoggerV2 creates a new LoggerV2 instance with the provided configuration. +// The infoW, warningW, and errorW writers are used to write log messages of +// different severity levels. +func NewLoggerV2(infoW, warningW, errorW io.Writer, c LoggerV2Config) LoggerV2 { + var m []*log.Logger + flag := log.LstdFlags + if c.FormatJSON { + flag = 0 + } + m = append(m, log.New(infoW, "", flag)) + m = append(m, log.New(io.MultiWriter(infoW, warningW), "", flag)) + ew := io.MultiWriter(infoW, warningW, errorW) // ew will be used for error and fatal. + m = append(m, log.New(ew, "", flag)) + m = append(m, log.New(ew, "", flag)) + return &loggerT{m: m, v: c.Verbosity, jsonFormat: c.FormatJSON} +} diff --git a/go-controller/vendor/google.golang.org/grpc/grpclog/logger.go b/go-controller/vendor/google.golang.org/grpc/grpclog/logger.go index b1674d8267..4b20358570 100644 --- a/go-controller/vendor/google.golang.org/grpc/grpclog/logger.go +++ b/go-controller/vendor/google.golang.org/grpc/grpclog/logger.go @@ -18,70 +18,17 @@ package grpclog -import "google.golang.org/grpc/internal/grpclog" +import "google.golang.org/grpc/grpclog/internal" // Logger mimics golang's standard Logger as an interface. // // Deprecated: use LoggerV2. -type Logger interface { - Fatal(args ...any) - Fatalf(format string, args ...any) - Fatalln(args ...any) - Print(args ...any) - Printf(format string, args ...any) - Println(args ...any) -} +type Logger internal.Logger // SetLogger sets the logger that is used in grpc. Call only from // init() functions. // // Deprecated: use SetLoggerV2. func SetLogger(l Logger) { - grpclog.Logger = &loggerWrapper{Logger: l} -} - -// loggerWrapper wraps Logger into a LoggerV2. -type loggerWrapper struct { - Logger -} - -func (g *loggerWrapper) Info(args ...any) { - g.Logger.Print(args...) -} - -func (g *loggerWrapper) Infoln(args ...any) { - g.Logger.Println(args...) -} - -func (g *loggerWrapper) Infof(format string, args ...any) { - g.Logger.Printf(format, args...) -} - -func (g *loggerWrapper) Warning(args ...any) { - g.Logger.Print(args...) -} - -func (g *loggerWrapper) Warningln(args ...any) { - g.Logger.Println(args...) -} - -func (g *loggerWrapper) Warningf(format string, args ...any) { - g.Logger.Printf(format, args...) -} - -func (g *loggerWrapper) Error(args ...any) { - g.Logger.Print(args...) -} - -func (g *loggerWrapper) Errorln(args ...any) { - g.Logger.Println(args...) -} - -func (g *loggerWrapper) Errorf(format string, args ...any) { - g.Logger.Printf(format, args...) -} - -func (g *loggerWrapper) V(l int) bool { - // Returns true for all verbose level. - return true + internal.LoggerV2Impl = &internal.LoggerWrapper{Logger: l} } diff --git a/go-controller/vendor/google.golang.org/grpc/grpclog/loggerv2.go b/go-controller/vendor/google.golang.org/grpc/grpclog/loggerv2.go index ecfd36d713..892dc13d16 100644 --- a/go-controller/vendor/google.golang.org/grpc/grpclog/loggerv2.go +++ b/go-controller/vendor/google.golang.org/grpc/grpclog/loggerv2.go @@ -19,52 +19,16 @@ package grpclog import ( - "encoding/json" - "fmt" "io" - "log" "os" "strconv" "strings" - "google.golang.org/grpc/internal/grpclog" + "google.golang.org/grpc/grpclog/internal" ) // LoggerV2 does underlying logging work for grpclog. -type LoggerV2 interface { - // Info logs to INFO log. Arguments are handled in the manner of fmt.Print. - Info(args ...any) - // Infoln logs to INFO log. Arguments are handled in the manner of fmt.Println. - Infoln(args ...any) - // Infof logs to INFO log. Arguments are handled in the manner of fmt.Printf. - Infof(format string, args ...any) - // Warning logs to WARNING log. Arguments are handled in the manner of fmt.Print. - Warning(args ...any) - // Warningln logs to WARNING log. Arguments are handled in the manner of fmt.Println. - Warningln(args ...any) - // Warningf logs to WARNING log. Arguments are handled in the manner of fmt.Printf. - Warningf(format string, args ...any) - // Error logs to ERROR log. Arguments are handled in the manner of fmt.Print. - Error(args ...any) - // Errorln logs to ERROR log. Arguments are handled in the manner of fmt.Println. - Errorln(args ...any) - // Errorf logs to ERROR log. Arguments are handled in the manner of fmt.Printf. - Errorf(format string, args ...any) - // Fatal logs to ERROR log. Arguments are handled in the manner of fmt.Print. - // gRPC ensures that all Fatal logs will exit with os.Exit(1). - // Implementations may also call os.Exit() with a non-zero exit code. - Fatal(args ...any) - // Fatalln logs to ERROR log. Arguments are handled in the manner of fmt.Println. - // gRPC ensures that all Fatal logs will exit with os.Exit(1). - // Implementations may also call os.Exit() with a non-zero exit code. - Fatalln(args ...any) - // Fatalf logs to ERROR log. Arguments are handled in the manner of fmt.Printf. - // gRPC ensures that all Fatal logs will exit with os.Exit(1). - // Implementations may also call os.Exit() with a non-zero exit code. - Fatalf(format string, args ...any) - // V reports whether verbosity level l is at least the requested verbose level. - V(l int) bool -} +type LoggerV2 internal.LoggerV2 // SetLoggerV2 sets logger that is used in grpc to a V2 logger. // Not mutex-protected, should be called before any gRPC functions. @@ -72,34 +36,8 @@ func SetLoggerV2(l LoggerV2) { if _, ok := l.(*componentData); ok { panic("cannot use component logger as grpclog logger") } - grpclog.Logger = l - grpclog.DepthLogger, _ = l.(grpclog.DepthLoggerV2) -} - -const ( - // infoLog indicates Info severity. - infoLog int = iota - // warningLog indicates Warning severity. - warningLog - // errorLog indicates Error severity. - errorLog - // fatalLog indicates Fatal severity. - fatalLog -) - -// severityName contains the string representation of each severity. -var severityName = []string{ - infoLog: "INFO", - warningLog: "WARNING", - errorLog: "ERROR", - fatalLog: "FATAL", -} - -// loggerT is the default logger used by grpclog. -type loggerT struct { - m []*log.Logger - v int - jsonFormat bool + internal.LoggerV2Impl = l + internal.DepthLoggerV2Impl, _ = l.(internal.DepthLoggerV2) } // NewLoggerV2 creates a loggerV2 with the provided writers. @@ -108,32 +46,13 @@ type loggerT struct { // Warning logs will be written to warningW and infoW. // Info logs will be written to infoW. func NewLoggerV2(infoW, warningW, errorW io.Writer) LoggerV2 { - return newLoggerV2WithConfig(infoW, warningW, errorW, loggerV2Config{}) + return internal.NewLoggerV2(infoW, warningW, errorW, internal.LoggerV2Config{}) } // NewLoggerV2WithVerbosity creates a loggerV2 with the provided writers and // verbosity level. func NewLoggerV2WithVerbosity(infoW, warningW, errorW io.Writer, v int) LoggerV2 { - return newLoggerV2WithConfig(infoW, warningW, errorW, loggerV2Config{verbose: v}) -} - -type loggerV2Config struct { - verbose int - jsonFormat bool -} - -func newLoggerV2WithConfig(infoW, warningW, errorW io.Writer, c loggerV2Config) LoggerV2 { - var m []*log.Logger - flag := log.LstdFlags - if c.jsonFormat { - flag = 0 - } - m = append(m, log.New(infoW, "", flag)) - m = append(m, log.New(io.MultiWriter(infoW, warningW), "", flag)) - ew := io.MultiWriter(infoW, warningW, errorW) // ew will be used for error and fatal. - m = append(m, log.New(ew, "", flag)) - m = append(m, log.New(ew, "", flag)) - return &loggerT{m: m, v: c.verbose, jsonFormat: c.jsonFormat} + return internal.NewLoggerV2(infoW, warningW, errorW, internal.LoggerV2Config{Verbosity: v}) } // newLoggerV2 creates a loggerV2 to be used as default logger. @@ -161,80 +80,10 @@ func newLoggerV2() LoggerV2 { jsonFormat := strings.EqualFold(os.Getenv("GRPC_GO_LOG_FORMATTER"), "json") - return newLoggerV2WithConfig(infoW, warningW, errorW, loggerV2Config{ - verbose: v, - jsonFormat: jsonFormat, - }) -} - -func (g *loggerT) output(severity int, s string) { - sevStr := severityName[severity] - if !g.jsonFormat { - g.m[severity].Output(2, fmt.Sprintf("%v: %v", sevStr, s)) - return - } - // TODO: we can also include the logging component, but that needs more - // (API) changes. - b, _ := json.Marshal(map[string]string{ - "severity": sevStr, - "message": s, + return internal.NewLoggerV2(infoW, warningW, errorW, internal.LoggerV2Config{ + Verbosity: v, + FormatJSON: jsonFormat, }) - g.m[severity].Output(2, string(b)) -} - -func (g *loggerT) Info(args ...any) { - g.output(infoLog, fmt.Sprint(args...)) -} - -func (g *loggerT) Infoln(args ...any) { - g.output(infoLog, fmt.Sprintln(args...)) -} - -func (g *loggerT) Infof(format string, args ...any) { - g.output(infoLog, fmt.Sprintf(format, args...)) -} - -func (g *loggerT) Warning(args ...any) { - g.output(warningLog, fmt.Sprint(args...)) -} - -func (g *loggerT) Warningln(args ...any) { - g.output(warningLog, fmt.Sprintln(args...)) -} - -func (g *loggerT) Warningf(format string, args ...any) { - g.output(warningLog, fmt.Sprintf(format, args...)) -} - -func (g *loggerT) Error(args ...any) { - g.output(errorLog, fmt.Sprint(args...)) -} - -func (g *loggerT) Errorln(args ...any) { - g.output(errorLog, fmt.Sprintln(args...)) -} - -func (g *loggerT) Errorf(format string, args ...any) { - g.output(errorLog, fmt.Sprintf(format, args...)) -} - -func (g *loggerT) Fatal(args ...any) { - g.output(fatalLog, fmt.Sprint(args...)) - os.Exit(1) -} - -func (g *loggerT) Fatalln(args ...any) { - g.output(fatalLog, fmt.Sprintln(args...)) - os.Exit(1) -} - -func (g *loggerT) Fatalf(format string, args ...any) { - g.output(fatalLog, fmt.Sprintf(format, args...)) - os.Exit(1) -} - -func (g *loggerT) V(l int) bool { - return l <= g.v } // DepthLoggerV2 logs at a specified call frame. If a LoggerV2 also implements @@ -245,14 +94,4 @@ func (g *loggerT) V(l int) bool { // // Notice: This type is EXPERIMENTAL and may be changed or removed in a // later release. -type DepthLoggerV2 interface { - LoggerV2 - // InfoDepth logs to INFO log at the specified depth. Arguments are handled in the manner of fmt.Println. - InfoDepth(depth int, args ...any) - // WarningDepth logs to WARNING log at the specified depth. Arguments are handled in the manner of fmt.Println. - WarningDepth(depth int, args ...any) - // ErrorDepth logs to ERROR log at the specified depth. Arguments are handled in the manner of fmt.Println. - ErrorDepth(depth int, args ...any) - // FatalDepth logs to FATAL log at the specified depth. Arguments are handled in the manner of fmt.Println. - FatalDepth(depth int, args ...any) -} +type DepthLoggerV2 internal.DepthLoggerV2 diff --git a/go-controller/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/config.go b/go-controller/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/config.go index 13821a9266..85540f86a7 100644 --- a/go-controller/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/config.go +++ b/go-controller/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/config.go @@ -33,6 +33,8 @@ type lbConfig struct { childConfig serviceconfig.LoadBalancingConfig } +// ChildName returns the name of the child balancer of the gracefulswitch +// Balancer. func ChildName(l serviceconfig.LoadBalancingConfig) string { return l.(*lbConfig).childBuilder.Name() } diff --git a/go-controller/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go b/go-controller/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go index aa4505a871..9669328914 100644 --- a/go-controller/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go +++ b/go-controller/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go @@ -106,7 +106,7 @@ func (ml *TruncatingMethodLogger) Build(c LogEntryConfig) *binlogpb.GrpcLogEntry } // Log creates a proto binary log entry, and logs it to the sink. -func (ml *TruncatingMethodLogger) Log(ctx context.Context, c LogEntryConfig) { +func (ml *TruncatingMethodLogger) Log(_ context.Context, c LogEntryConfig) { ml.sink.Write(ml.Build(c)) } diff --git a/go-controller/vendor/google.golang.org/grpc/internal/channelz/channel.go b/go-controller/vendor/google.golang.org/grpc/internal/channelz/channel.go index d7e9e1d54e..3ec662799a 100644 --- a/go-controller/vendor/google.golang.org/grpc/internal/channelz/channel.go +++ b/go-controller/vendor/google.golang.org/grpc/internal/channelz/channel.go @@ -43,6 +43,8 @@ type Channel struct { // Non-zero traceRefCount means the trace of this channel cannot be deleted. traceRefCount int32 + // ChannelMetrics holds connectivity state, target and call metrics for the + // channel within channelz. ChannelMetrics ChannelMetrics } @@ -50,6 +52,8 @@ type Channel struct { // nesting. func (c *Channel) channelzIdentifier() {} +// String returns a string representation of the Channel, including its parent +// entity and ID. func (c *Channel) String() string { if c.Parent == nil { return fmt.Sprintf("Channel #%d", c.ID) @@ -61,24 +65,31 @@ func (c *Channel) id() int64 { return c.ID } +// SubChans returns a copy of the map of sub-channels associated with the +// Channel. func (c *Channel) SubChans() map[int64]string { db.mu.RLock() defer db.mu.RUnlock() return copyMap(c.subChans) } +// NestedChans returns a copy of the map of nested channels associated with the +// Channel. func (c *Channel) NestedChans() map[int64]string { db.mu.RLock() defer db.mu.RUnlock() return copyMap(c.nestedChans) } +// Trace returns a copy of the Channel's trace data. func (c *Channel) Trace() *ChannelTrace { db.mu.RLock() defer db.mu.RUnlock() return c.trace.copy() } +// ChannelMetrics holds connectivity state, target and call metrics for the +// channel within channelz. type ChannelMetrics struct { // The current connectivity state of the channel. State atomic.Pointer[connectivity.State] @@ -136,12 +147,16 @@ func strFromPointer(s *string) string { return *s } +// String returns a string representation of the ChannelMetrics, including its +// state, target, and call metrics. func (c *ChannelMetrics) String() string { return fmt.Sprintf("State: %v, Target: %s, CallsStarted: %v, CallsSucceeded: %v, CallsFailed: %v, LastCallStartedTimestamp: %v", c.State.Load(), strFromPointer(c.Target.Load()), c.CallsStarted.Load(), c.CallsSucceeded.Load(), c.CallsFailed.Load(), c.LastCallStartedTimestamp.Load(), ) } +// NewChannelMetricForTesting creates a new instance of ChannelMetrics with +// specified initial values for testing purposes. func NewChannelMetricForTesting(state connectivity.State, target string, started, succeeded, failed, timestamp int64) *ChannelMetrics { c := &ChannelMetrics{} c.State.Store(&state) diff --git a/go-controller/vendor/google.golang.org/grpc/internal/channelz/channelmap.go b/go-controller/vendor/google.golang.org/grpc/internal/channelz/channelmap.go index dfe18b0892..64c791953d 100644 --- a/go-controller/vendor/google.golang.org/grpc/internal/channelz/channelmap.go +++ b/go-controller/vendor/google.golang.org/grpc/internal/channelz/channelmap.go @@ -46,7 +46,7 @@ type entry interface { // channelMap is the storage data structure for channelz. // -// Methods of channelMap can be divided in two two categories with respect to +// Methods of channelMap can be divided into two categories with respect to // locking. // // 1. Methods acquire the global lock. @@ -234,13 +234,6 @@ func copyMap(m map[int64]string) map[int64]string { return n } -func min(a, b int) int { - if a < b { - return a - } - return b -} - func (c *channelMap) getTopChannels(id int64, maxResults int) ([]*Channel, bool) { if maxResults <= 0 { maxResults = EntriesPerPage diff --git a/go-controller/vendor/google.golang.org/grpc/internal/channelz/funcs.go b/go-controller/vendor/google.golang.org/grpc/internal/channelz/funcs.go index 03e24e1507..078bb81238 100644 --- a/go-controller/vendor/google.golang.org/grpc/internal/channelz/funcs.go +++ b/go-controller/vendor/google.golang.org/grpc/internal/channelz/funcs.go @@ -33,7 +33,7 @@ var ( // outside this package except by tests. IDGen IDGenerator - db *channelMap = newChannelMap() + db = newChannelMap() // EntriesPerPage defines the number of channelz entries to be shown on a web page. EntriesPerPage = 50 curState int32 diff --git a/go-controller/vendor/google.golang.org/grpc/internal/channelz/server.go b/go-controller/vendor/google.golang.org/grpc/internal/channelz/server.go index cdfc49d6ea..b5a8249929 100644 --- a/go-controller/vendor/google.golang.org/grpc/internal/channelz/server.go +++ b/go-controller/vendor/google.golang.org/grpc/internal/channelz/server.go @@ -59,6 +59,8 @@ func NewServerMetricsForTesting(started, succeeded, failed, timestamp int64) *Se return sm } +// CopyFrom copies the metrics data from the provided ServerMetrics +// instance into the current instance. func (sm *ServerMetrics) CopyFrom(o *ServerMetrics) { sm.CallsStarted.Store(o.CallsStarted.Load()) sm.CallsSucceeded.Store(o.CallsSucceeded.Load()) diff --git a/go-controller/vendor/google.golang.org/grpc/internal/channelz/socket.go b/go-controller/vendor/google.golang.org/grpc/internal/channelz/socket.go index fa64834b25..90103847c5 100644 --- a/go-controller/vendor/google.golang.org/grpc/internal/channelz/socket.go +++ b/go-controller/vendor/google.golang.org/grpc/internal/channelz/socket.go @@ -70,13 +70,18 @@ type EphemeralSocketMetrics struct { RemoteFlowControlWindow int64 } +// SocketType represents the type of socket. type SocketType string +// SocketType can be one of these. const ( SocketTypeNormal = "NormalSocket" SocketTypeListen = "ListenSocket" ) +// Socket represents a socket within channelz which includes socket +// metrics and data related to socket activity and provides methods +// for managing and interacting with sockets. type Socket struct { Entity SocketType SocketType @@ -100,6 +105,8 @@ type Socket struct { Security credentials.ChannelzSecurityValue } +// String returns a string representation of the Socket, including its parent +// entity, socket type, and ID. func (ls *Socket) String() string { return fmt.Sprintf("%s %s #%d", ls.Parent, ls.SocketType, ls.ID) } diff --git a/go-controller/vendor/google.golang.org/grpc/internal/channelz/subchannel.go b/go-controller/vendor/google.golang.org/grpc/internal/channelz/subchannel.go index 3b88e4cba8..b20802e6e9 100644 --- a/go-controller/vendor/google.golang.org/grpc/internal/channelz/subchannel.go +++ b/go-controller/vendor/google.golang.org/grpc/internal/channelz/subchannel.go @@ -47,12 +47,14 @@ func (sc *SubChannel) id() int64 { return sc.ID } +// Sockets returns a copy of the sockets map associated with the SubChannel. func (sc *SubChannel) Sockets() map[int64]string { db.mu.RLock() defer db.mu.RUnlock() return copyMap(sc.sockets) } +// Trace returns a copy of the ChannelTrace associated with the SubChannel. func (sc *SubChannel) Trace() *ChannelTrace { db.mu.RLock() defer db.mu.RUnlock() diff --git a/go-controller/vendor/google.golang.org/grpc/internal/channelz/syscall_nonlinux.go b/go-controller/vendor/google.golang.org/grpc/internal/channelz/syscall_nonlinux.go index d1ed8df6a5..0e6e18e185 100644 --- a/go-controller/vendor/google.golang.org/grpc/internal/channelz/syscall_nonlinux.go +++ b/go-controller/vendor/google.golang.org/grpc/internal/channelz/syscall_nonlinux.go @@ -35,13 +35,13 @@ type SocketOptionData struct { // Getsockopt defines the function to get socket options requested by channelz. // It is to be passed to syscall.RawConn.Control(). // Windows OS doesn't support Socket Option -func (s *SocketOptionData) Getsockopt(fd uintptr) { +func (s *SocketOptionData) Getsockopt(uintptr) { once.Do(func() { logger.Warning("Channelz: socket options are not supported on non-linux environments") }) } // GetSocketOption gets the socket option info of the conn. -func GetSocketOption(c any) *SocketOptionData { +func GetSocketOption(any) *SocketOptionData { return nil } diff --git a/go-controller/vendor/google.golang.org/grpc/internal/channelz/trace.go b/go-controller/vendor/google.golang.org/grpc/internal/channelz/trace.go index 36b8674032..2bffe47776 100644 --- a/go-controller/vendor/google.golang.org/grpc/internal/channelz/trace.go +++ b/go-controller/vendor/google.golang.org/grpc/internal/channelz/trace.go @@ -79,13 +79,21 @@ type TraceEvent struct { Parent *TraceEvent } +// ChannelTrace provides tracing information for a channel. +// It tracks various events and metadata related to the channel's lifecycle +// and operations. type ChannelTrace struct { - cm *channelMap - clearCalled bool + cm *channelMap + clearCalled bool + // The time when the trace was created. CreationTime time.Time - EventNum int64 - mu sync.Mutex - Events []*traceEvent + // A counter for the number of events recorded in the + // trace. + EventNum int64 + mu sync.Mutex + // A slice of traceEvent pointers representing the events recorded for + // this channel. + Events []*traceEvent } func (c *ChannelTrace) copy() *ChannelTrace { @@ -175,6 +183,7 @@ var refChannelTypeToString = map[RefChannelType]string{ RefNormalSocket: "NormalSocket", } +// String returns a string representation of the RefChannelType func (r RefChannelType) String() string { return refChannelTypeToString[r] } diff --git a/go-controller/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go b/go-controller/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go index d906487139..6e7dd6b772 100644 --- a/go-controller/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go +++ b/go-controller/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go @@ -45,7 +45,16 @@ var ( // option is present for backward compatibility. This option may be overridden // by setting the environment variable "GRPC_ENFORCE_ALPN_ENABLED" to "true" // or "false". - EnforceALPNEnabled = boolFromEnv("GRPC_ENFORCE_ALPN_ENABLED", false) + EnforceALPNEnabled = boolFromEnv("GRPC_ENFORCE_ALPN_ENABLED", true) + // XDSFallbackSupport is the env variable that controls whether support for + // xDS fallback is turned on. If this is unset or is false, only the first + // xDS server in the list of server configs will be used. + XDSFallbackSupport = boolFromEnv("GRPC_EXPERIMENTAL_XDS_FALLBACK", false) + // NewPickFirstEnabled is set if the new pickfirst leaf policy is to be used + // instead of the exiting pickfirst implementation. This can be enabled by + // setting the environment variable "GRPC_EXPERIMENTAL_ENABLE_NEW_PICK_FIRST" + // to "true". + NewPickFirstEnabled = boolFromEnv("GRPC_EXPERIMENTAL_ENABLE_NEW_PICK_FIRST", false) ) func boolFromEnv(envVar string, def bool) bool { diff --git a/go-controller/vendor/google.golang.org/grpc/internal/experimental.go b/go-controller/vendor/google.golang.org/grpc/internal/experimental.go index 7f7044e173..7617be2158 100644 --- a/go-controller/vendor/google.golang.org/grpc/internal/experimental.go +++ b/go-controller/vendor/google.golang.org/grpc/internal/experimental.go @@ -18,11 +18,11 @@ package internal var ( - // WithRecvBufferPool is implemented by the grpc package and returns a dial + // WithBufferPool is implemented by the grpc package and returns a dial // option to configure a shared buffer pool for a grpc.ClientConn. - WithRecvBufferPool any // func (grpc.SharedBufferPool) grpc.DialOption + WithBufferPool any // func (grpc.SharedBufferPool) grpc.DialOption - // RecvBufferPool is implemented by the grpc package and returns a server + // BufferPool is implemented by the grpc package and returns a server // option to configure a shared buffer pool for a grpc.Server. - RecvBufferPool any // func (grpc.SharedBufferPool) grpc.ServerOption + BufferPool any // func (grpc.SharedBufferPool) grpc.ServerOption ) diff --git a/go-controller/vendor/google.golang.org/grpc/internal/grpclog/prefixLogger.go b/go-controller/vendor/google.golang.org/grpc/internal/grpclog/prefix_logger.go similarity index 63% rename from go-controller/vendor/google.golang.org/grpc/internal/grpclog/prefixLogger.go rename to go-controller/vendor/google.golang.org/grpc/internal/grpclog/prefix_logger.go index faa998de76..092ad187a2 100644 --- a/go-controller/vendor/google.golang.org/grpc/internal/grpclog/prefixLogger.go +++ b/go-controller/vendor/google.golang.org/grpc/internal/grpclog/prefix_logger.go @@ -16,17 +16,21 @@ * */ +// Package grpclog provides logging functionality for internal gRPC packages, +// outside of the functionality provided by the external `grpclog` package. package grpclog import ( "fmt" + + "google.golang.org/grpc/grpclog" ) // PrefixLogger does logging with a prefix. // // Logging method on a nil logs without any prefix. type PrefixLogger struct { - logger DepthLoggerV2 + logger grpclog.DepthLoggerV2 prefix string } @@ -38,7 +42,7 @@ func (pl *PrefixLogger) Infof(format string, args ...any) { pl.logger.InfoDepth(1, fmt.Sprintf(format, args...)) return } - InfoDepth(1, fmt.Sprintf(format, args...)) + grpclog.InfoDepth(1, fmt.Sprintf(format, args...)) } // Warningf does warning logging. @@ -48,7 +52,7 @@ func (pl *PrefixLogger) Warningf(format string, args ...any) { pl.logger.WarningDepth(1, fmt.Sprintf(format, args...)) return } - WarningDepth(1, fmt.Sprintf(format, args...)) + grpclog.WarningDepth(1, fmt.Sprintf(format, args...)) } // Errorf does error logging. @@ -58,36 +62,18 @@ func (pl *PrefixLogger) Errorf(format string, args ...any) { pl.logger.ErrorDepth(1, fmt.Sprintf(format, args...)) return } - ErrorDepth(1, fmt.Sprintf(format, args...)) -} - -// Debugf does info logging at verbose level 2. -func (pl *PrefixLogger) Debugf(format string, args ...any) { - // TODO(6044): Refactor interfaces LoggerV2 and DepthLogger, and maybe - // rewrite PrefixLogger a little to ensure that we don't use the global - // `Logger` here, and instead use the `logger` field. - if !Logger.V(2) { - return - } - if pl != nil { - // Handle nil, so the tests can pass in a nil logger. - format = pl.prefix + format - pl.logger.InfoDepth(1, fmt.Sprintf(format, args...)) - return - } - InfoDepth(1, fmt.Sprintf(format, args...)) - + grpclog.ErrorDepth(1, fmt.Sprintf(format, args...)) } // V reports whether verbosity level l is at least the requested verbose level. func (pl *PrefixLogger) V(l int) bool { - // TODO(6044): Refactor interfaces LoggerV2 and DepthLogger, and maybe - // rewrite PrefixLogger a little to ensure that we don't use the global - // `Logger` here, and instead use the `logger` field. - return Logger.V(l) + if pl != nil { + return pl.logger.V(l) + } + return true } // NewPrefixLogger creates a prefix logger with the given prefix. -func NewPrefixLogger(logger DepthLoggerV2, prefix string) *PrefixLogger { +func NewPrefixLogger(logger grpclog.DepthLoggerV2, prefix string) *PrefixLogger { return &PrefixLogger{logger: logger, prefix: prefix} } diff --git a/go-controller/vendor/google.golang.org/grpc/internal/grpcsync/callback_serializer.go b/go-controller/vendor/google.golang.org/grpc/internal/grpcsync/callback_serializer.go index f7f40a16ac..8e8e861280 100644 --- a/go-controller/vendor/google.golang.org/grpc/internal/grpcsync/callback_serializer.go +++ b/go-controller/vendor/google.golang.org/grpc/internal/grpcsync/callback_serializer.go @@ -53,16 +53,28 @@ func NewCallbackSerializer(ctx context.Context) *CallbackSerializer { return cs } -// Schedule adds a callback to be scheduled after existing callbacks are run. +// TrySchedule tries to schedule the provided callback function f to be +// executed in the order it was added. This is a best-effort operation. If the +// context passed to NewCallbackSerializer was canceled before this method is +// called, the callback will not be scheduled. // // Callbacks are expected to honor the context when performing any blocking // operations, and should return early when the context is canceled. +func (cs *CallbackSerializer) TrySchedule(f func(ctx context.Context)) { + cs.callbacks.Put(f) +} + +// ScheduleOr schedules the provided callback function f to be executed in the +// order it was added. If the context passed to NewCallbackSerializer has been +// canceled before this method is called, the onFailure callback will be +// executed inline instead. // -// Return value indicates if the callback was successfully added to the list of -// callbacks to be executed by the serializer. It is not possible to add -// callbacks once the context passed to NewCallbackSerializer is cancelled. -func (cs *CallbackSerializer) Schedule(f func(ctx context.Context)) bool { - return cs.callbacks.Put(f) == nil +// Callbacks are expected to honor the context when performing any blocking +// operations, and should return early when the context is canceled. +func (cs *CallbackSerializer) ScheduleOr(f func(ctx context.Context), onFailure func()) { + if cs.callbacks.Put(f) != nil { + onFailure() + } } func (cs *CallbackSerializer) run(ctx context.Context) { diff --git a/go-controller/vendor/google.golang.org/grpc/internal/grpcsync/pubsub.go b/go-controller/vendor/google.golang.org/grpc/internal/grpcsync/pubsub.go index aef8cec1ab..6d8c2f518d 100644 --- a/go-controller/vendor/google.golang.org/grpc/internal/grpcsync/pubsub.go +++ b/go-controller/vendor/google.golang.org/grpc/internal/grpcsync/pubsub.go @@ -77,7 +77,7 @@ func (ps *PubSub) Subscribe(sub Subscriber) (cancel func()) { if ps.msg != nil { msg := ps.msg - ps.cs.Schedule(func(context.Context) { + ps.cs.TrySchedule(func(context.Context) { ps.mu.Lock() defer ps.mu.Unlock() if !ps.subscribers[sub] { @@ -103,7 +103,7 @@ func (ps *PubSub) Publish(msg any) { ps.msg = msg for sub := range ps.subscribers { s := sub - ps.cs.Schedule(func(context.Context) { + ps.cs.TrySchedule(func(context.Context) { ps.mu.Lock() defer ps.mu.Unlock() if !ps.subscribers[s] { diff --git a/go-controller/vendor/google.golang.org/grpc/internal/grpcutil/method.go b/go-controller/vendor/google.golang.org/grpc/internal/grpcutil/method.go index ec62b4775e..683d1955c6 100644 --- a/go-controller/vendor/google.golang.org/grpc/internal/grpcutil/method.go +++ b/go-controller/vendor/google.golang.org/grpc/internal/grpcutil/method.go @@ -39,7 +39,7 @@ func ParseMethod(methodName string) (service, method string, _ error) { } // baseContentType is the base content-type for gRPC. This is a valid -// content-type on it's own, but can also include a content-subtype such as +// content-type on its own, but can also include a content-subtype such as // "proto" as a suffix after "+" or ";". See // https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests // for more details. diff --git a/go-controller/vendor/google.golang.org/grpc/internal/idle/idle.go b/go-controller/vendor/google.golang.org/grpc/internal/idle/idle.go index fe49cb74c5..2c13ee9dac 100644 --- a/go-controller/vendor/google.golang.org/grpc/internal/idle/idle.go +++ b/go-controller/vendor/google.golang.org/grpc/internal/idle/idle.go @@ -182,6 +182,7 @@ func (m *Manager) tryEnterIdleMode() bool { return true } +// EnterIdleModeForTesting instructs the channel to enter idle mode. func (m *Manager) EnterIdleModeForTesting() { m.tryEnterIdleMode() } @@ -225,7 +226,7 @@ func (m *Manager) ExitIdleMode() error { // came in and OnCallBegin() noticed that the calls count is negative. // - Channel is in idle mode, and multiple new RPCs come in at the same // time, all of them notice a negative calls count in OnCallBegin and get - // here. The first one to get the lock would got the channel to exit idle. + // here. The first one to get the lock would get the channel to exit idle. // - Channel is not in idle mode, and the user calls Connect which calls // m.ExitIdleMode. // @@ -266,6 +267,7 @@ func (m *Manager) isClosed() bool { return atomic.LoadInt32(&m.closed) == 1 } +// Close stops the timer associated with the Manager, if it exists. func (m *Manager) Close() { atomic.StoreInt32(&m.closed, 1) diff --git a/go-controller/vendor/google.golang.org/grpc/internal/internal.go b/go-controller/vendor/google.golang.org/grpc/internal/internal.go index 5d66539869..20b4dc3d35 100644 --- a/go-controller/vendor/google.golang.org/grpc/internal/internal.go +++ b/go-controller/vendor/google.golang.org/grpc/internal/internal.go @@ -183,7 +183,7 @@ var ( // GRPCResolverSchemeExtraMetadata determines when gRPC will add extra // metadata to RPCs. - GRPCResolverSchemeExtraMetadata string = "xds" + GRPCResolverSchemeExtraMetadata = "xds" // EnterIdleModeForTesting gets the ClientConn to enter IDLE mode. EnterIdleModeForTesting any // func(*grpc.ClientConn) @@ -191,6 +191,8 @@ var ( // ExitIdleModeForTesting gets the ClientConn to exit IDLE mode. ExitIdleModeForTesting any // func(*grpc.ClientConn) error + // ChannelzTurnOffForTesting disables the Channelz service for testing + // purposes. ChannelzTurnOffForTesting func() // TriggerXDSResourceNotFoundForTesting causes the provided xDS Client to @@ -203,11 +205,27 @@ var ( // UserSetDefaultScheme is set to true if the user has overridden the // default resolver scheme. - UserSetDefaultScheme bool = false + UserSetDefaultScheme = false - // ShuffleAddressListForTesting pseudo-randomizes the order of addresses. n - // is the number of elements. swap swaps the elements with indexes i and j. - ShuffleAddressListForTesting any // func(n int, swap func(i, j int)) + // ConnectedAddress returns the connected address for a SubConnState. The + // address is only valid if the state is READY. + ConnectedAddress any // func (scs SubConnState) resolver.Address + + // SetConnectedAddress sets the connected address for a SubConnState. + SetConnectedAddress any // func(scs *SubConnState, addr resolver.Address) + + // SnapshotMetricRegistryForTesting snapshots the global data of the metric + // registry. Returns a cleanup function that sets the metric registry to its + // original state. Only called in testing functions. + SnapshotMetricRegistryForTesting func() func() + + // SetDefaultBufferPoolForTesting updates the default buffer pool, for + // testing purposes. + SetDefaultBufferPoolForTesting any // func(mem.BufferPool) + + // SetBufferPoolingThresholdForTesting updates the buffer pooling threshold, for + // testing purposes. + SetBufferPoolingThresholdForTesting any // func(int) ) // HealthChecker defines the signature of the client-side LB channel health @@ -215,7 +233,7 @@ var ( // // The implementation is expected to create a health checking RPC stream by // calling newStream(), watch for the health status of serviceName, and report -// it's health back by calling setConnectivityState(). +// its health back by calling setConnectivityState(). // // The health checking protocol is defined at: // https://github.com/grpc/grpc/blob/master/doc/health-checking.md diff --git a/go-controller/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go b/go-controller/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go index 4552db16b0..374c12fb77 100644 --- a/go-controller/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go +++ b/go-controller/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go @@ -177,7 +177,7 @@ type dnsResolver struct { // finished. Otherwise, data race will be possible. [Race Example] in // dns_resolver_test we replace the real lookup functions with mocked ones to // facilitate testing. If Close() doesn't wait for watcher() goroutine - // finishes, race detector sometimes will warns lookup (READ the lookup + // finishes, race detector sometimes will warn lookup (READ the lookup // function pointers) inside watcher() goroutine has data race with // replaceNetFunc (WRITE the lookup function pointers). wg sync.WaitGroup @@ -237,7 +237,9 @@ func (d *dnsResolver) watcher() { } func (d *dnsResolver) lookupSRV(ctx context.Context) ([]resolver.Address, error) { - if !EnableSRVLookups { + // Skip this particular host to avoid timeouts with some versions of + // systemd-resolved. + if !EnableSRVLookups || d.host == "metadata.google.internal." { return nil, nil } var newAddrs []resolver.Address diff --git a/go-controller/vendor/google.golang.org/grpc/internal/resolver/passthrough/passthrough.go b/go-controller/vendor/google.golang.org/grpc/internal/resolver/passthrough/passthrough.go index afac56572a..b901c7bace 100644 --- a/go-controller/vendor/google.golang.org/grpc/internal/resolver/passthrough/passthrough.go +++ b/go-controller/vendor/google.golang.org/grpc/internal/resolver/passthrough/passthrough.go @@ -55,7 +55,7 @@ func (r *passthroughResolver) start() { r.cc.UpdateState(resolver.State{Addresses: []resolver.Address{{Addr: r.target.Endpoint()}}}) } -func (*passthroughResolver) ResolveNow(o resolver.ResolveNowOptions) {} +func (*passthroughResolver) ResolveNow(resolver.ResolveNowOptions) {} func (*passthroughResolver) Close() {} diff --git a/go-controller/vendor/google.golang.org/grpc/internal/stats/labels.go b/go-controller/vendor/google.golang.org/grpc/internal/stats/labels.go new file mode 100644 index 0000000000..fd33af51ae --- /dev/null +++ b/go-controller/vendor/google.golang.org/grpc/internal/stats/labels.go @@ -0,0 +1,42 @@ +/* + * + * Copyright 2024 gRPC authors. + * + * 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 stats provides internal stats related functionality. +package stats + +import "context" + +// Labels are the labels for metrics. +type Labels struct { + // TelemetryLabels are the telemetry labels to record. + TelemetryLabels map[string]string +} + +type labelsKey struct{} + +// GetLabels returns the Labels stored in the context, or nil if there is one. +func GetLabels(ctx context.Context) *Labels { + labels, _ := ctx.Value(labelsKey{}).(*Labels) + return labels +} + +// SetLabels sets the Labels in the context. +func SetLabels(ctx context.Context, labels *Labels) context.Context { + // could also append + return context.WithValue(ctx, labelsKey{}, labels) +} diff --git a/go-controller/vendor/google.golang.org/grpc/internal/stats/metrics_recorder_list.go b/go-controller/vendor/google.golang.org/grpc/internal/stats/metrics_recorder_list.go new file mode 100644 index 0000000000..79044657be --- /dev/null +++ b/go-controller/vendor/google.golang.org/grpc/internal/stats/metrics_recorder_list.go @@ -0,0 +1,105 @@ +/* + * Copyright 2024 gRPC authors. + * + * 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 stats + +import ( + "fmt" + + estats "google.golang.org/grpc/experimental/stats" + "google.golang.org/grpc/stats" +) + +// MetricsRecorderList forwards Record calls to all of its metricsRecorders. +// +// It eats any record calls where the label values provided do not match the +// number of label keys. +type MetricsRecorderList struct { + // metricsRecorders are the metrics recorders this list will forward to. + metricsRecorders []estats.MetricsRecorder +} + +// NewMetricsRecorderList creates a new metric recorder list with all the stats +// handlers provided which implement the MetricsRecorder interface. +// If no stats handlers provided implement the MetricsRecorder interface, +// the MetricsRecorder list returned is a no-op. +func NewMetricsRecorderList(shs []stats.Handler) *MetricsRecorderList { + var mrs []estats.MetricsRecorder + for _, sh := range shs { + if mr, ok := sh.(estats.MetricsRecorder); ok { + mrs = append(mrs, mr) + } + } + return &MetricsRecorderList{ + metricsRecorders: mrs, + } +} + +func verifyLabels(desc *estats.MetricDescriptor, labelsRecv ...string) { + if got, want := len(labelsRecv), len(desc.Labels)+len(desc.OptionalLabels); got != want { + panic(fmt.Sprintf("Received %d labels in call to record metric %q, but expected %d.", got, desc.Name, want)) + } +} + +// RecordInt64Count records the measurement alongside labels on the int +// count associated with the provided handle. +func (l *MetricsRecorderList) RecordInt64Count(handle *estats.Int64CountHandle, incr int64, labels ...string) { + verifyLabels(handle.Descriptor(), labels...) + + for _, metricRecorder := range l.metricsRecorders { + metricRecorder.RecordInt64Count(handle, incr, labels...) + } +} + +// RecordFloat64Count records the measurement alongside labels on the float +// count associated with the provided handle. +func (l *MetricsRecorderList) RecordFloat64Count(handle *estats.Float64CountHandle, incr float64, labels ...string) { + verifyLabels(handle.Descriptor(), labels...) + + for _, metricRecorder := range l.metricsRecorders { + metricRecorder.RecordFloat64Count(handle, incr, labels...) + } +} + +// RecordInt64Histo records the measurement alongside labels on the int +// histo associated with the provided handle. +func (l *MetricsRecorderList) RecordInt64Histo(handle *estats.Int64HistoHandle, incr int64, labels ...string) { + verifyLabels(handle.Descriptor(), labels...) + + for _, metricRecorder := range l.metricsRecorders { + metricRecorder.RecordInt64Histo(handle, incr, labels...) + } +} + +// RecordFloat64Histo records the measurement alongside labels on the float +// histo associated with the provided handle. +func (l *MetricsRecorderList) RecordFloat64Histo(handle *estats.Float64HistoHandle, incr float64, labels ...string) { + verifyLabels(handle.Descriptor(), labels...) + + for _, metricRecorder := range l.metricsRecorders { + metricRecorder.RecordFloat64Histo(handle, incr, labels...) + } +} + +// RecordInt64Gauge records the measurement alongside labels on the int +// gauge associated with the provided handle. +func (l *MetricsRecorderList) RecordInt64Gauge(handle *estats.Int64GaugeHandle, incr int64, labels ...string) { + verifyLabels(handle.Descriptor(), labels...) + + for _, metricRecorder := range l.metricsRecorders { + metricRecorder.RecordInt64Gauge(handle, incr, labels...) + } +} diff --git a/go-controller/vendor/google.golang.org/grpc/internal/status/status.go b/go-controller/vendor/google.golang.org/grpc/internal/status/status.go index c7dbc82059..1186f1e9a9 100644 --- a/go-controller/vendor/google.golang.org/grpc/internal/status/status.go +++ b/go-controller/vendor/google.golang.org/grpc/internal/status/status.go @@ -138,17 +138,19 @@ func (s *Status) WithDetails(details ...protoadapt.MessageV1) (*Status, error) { // s.Code() != OK implies that s.Proto() != nil. p := s.Proto() for _, detail := range details { - any, err := anypb.New(protoadapt.MessageV2Of(detail)) + m, err := anypb.New(protoadapt.MessageV2Of(detail)) if err != nil { return nil, err } - p.Details = append(p.Details, any) + p.Details = append(p.Details, m) } return &Status{s: p}, nil } // Details returns a slice of details messages attached to the status. // If a detail cannot be decoded, the error is returned in place of the detail. +// If the detail can be decoded, the proto message returned is of the same +// type that was given to WithDetails(). func (s *Status) Details() []any { if s == nil || s.s == nil { return nil @@ -160,7 +162,38 @@ func (s *Status) Details() []any { details = append(details, err) continue } - details = append(details, detail) + // The call to MessageV1Of is required to unwrap the proto message if + // it implemented only the MessageV1 API. The proto message would have + // been wrapped in a V2 wrapper in Status.WithDetails. V2 messages are + // added to a global registry used by any.UnmarshalNew(). + // MessageV1Of has the following behaviour: + // 1. If the given message is a wrapped MessageV1, it returns the + // unwrapped value. + // 2. If the given message already implements MessageV1, it returns it + // as is. + // 3. Else, it wraps the MessageV2 in a MessageV1 wrapper. + // + // Since the Status.WithDetails() API only accepts MessageV1, calling + // MessageV1Of ensures we return the same type that was given to + // WithDetails: + // * If the give type implemented only MessageV1, the unwrapping from + // point 1 above will restore the type. + // * If the given type implemented both MessageV1 and MessageV2, point 2 + // above will ensure no wrapping is performed. + // * If the given type implemented only MessageV2 and was wrapped using + // MessageV1Of before passing to WithDetails(), it would be unwrapped + // in WithDetails by calling MessageV2Of(). Point 3 above will ensure + // that the type is wrapped in a MessageV1 wrapper again before + // returning. Note that protoc-gen-go doesn't generate code which + // implements ONLY MessageV2 at the time of writing. + // + // NOTE: Status details can also be added using the FromProto method. + // This could theoretically allow passing a Detail message that only + // implements the V2 API. In such a case the message will be wrapped in + // a MessageV1 wrapper when fetched using Details(). + // Since protoc-gen-go generates only code that implements both V1 and + // V2 APIs for backward compatibility, this is not a concern. + details = append(details, protoadapt.MessageV1Of(detail)) } return details } diff --git a/go-controller/vendor/google.golang.org/grpc/internal/syscall/syscall_nonlinux.go b/go-controller/vendor/google.golang.org/grpc/internal/syscall/syscall_nonlinux.go index 999f52cd75..54c24c2ff3 100644 --- a/go-controller/vendor/google.golang.org/grpc/internal/syscall/syscall_nonlinux.go +++ b/go-controller/vendor/google.golang.org/grpc/internal/syscall/syscall_nonlinux.go @@ -58,20 +58,20 @@ func GetRusage() *Rusage { // CPUTimeDiff returns the differences of user CPU time and system CPU time used // between two Rusage structs. It a no-op function for non-linux environments. -func CPUTimeDiff(first *Rusage, latest *Rusage) (float64, float64) { +func CPUTimeDiff(*Rusage, *Rusage) (float64, float64) { log() return 0, 0 } // SetTCPUserTimeout is a no-op function under non-linux environments. -func SetTCPUserTimeout(conn net.Conn, timeout time.Duration) error { +func SetTCPUserTimeout(net.Conn, time.Duration) error { log() return nil } // GetTCPUserTimeout is a no-op function under non-linux environments. // A negative return value indicates the operation is not supported -func GetTCPUserTimeout(conn net.Conn) (int, error) { +func GetTCPUserTimeout(net.Conn) (int, error) { log() return -1, nil } diff --git a/go-controller/vendor/google.golang.org/grpc/internal/tcp_keepalive_unix.go b/go-controller/vendor/google.golang.org/grpc/internal/tcp_keepalive_unix.go index 078137b7fd..7e7aaa5463 100644 --- a/go-controller/vendor/google.golang.org/grpc/internal/tcp_keepalive_unix.go +++ b/go-controller/vendor/google.golang.org/grpc/internal/tcp_keepalive_unix.go @@ -44,7 +44,7 @@ func NetDialerWithTCPKeepalive() *net.Dialer { // combination of unconditionally enabling TCP keepalives here, and // disabling the overriding of TCP keepalive parameters by setting the // KeepAlive field to a negative value above, results in OS defaults for - // the TCP keealive interval and time parameters. + // the TCP keepalive interval and time parameters. Control: func(_, _ string, c syscall.RawConn) error { return c.Control(func(fd uintptr) { unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_KEEPALIVE, 1) diff --git a/go-controller/vendor/google.golang.org/grpc/internal/tcp_keepalive_windows.go b/go-controller/vendor/google.golang.org/grpc/internal/tcp_keepalive_windows.go index fd7d43a890..d5c1085eea 100644 --- a/go-controller/vendor/google.golang.org/grpc/internal/tcp_keepalive_windows.go +++ b/go-controller/vendor/google.golang.org/grpc/internal/tcp_keepalive_windows.go @@ -44,7 +44,7 @@ func NetDialerWithTCPKeepalive() *net.Dialer { // combination of unconditionally enabling TCP keepalives here, and // disabling the overriding of TCP keepalive parameters by setting the // KeepAlive field to a negative value above, results in OS defaults for - // the TCP keealive interval and time parameters. + // the TCP keepalive interval and time parameters. Control: func(_, _ string, c syscall.RawConn) error { return c.Control(func(fd uintptr) { windows.SetsockoptInt(windows.Handle(fd), windows.SOL_SOCKET, windows.SO_KEEPALIVE, 1) diff --git a/go-controller/vendor/google.golang.org/grpc/internal/transport/controlbuf.go b/go-controller/vendor/google.golang.org/grpc/internal/transport/controlbuf.go index 3deadfb4a2..ef72fbb3a0 100644 --- a/go-controller/vendor/google.golang.org/grpc/internal/transport/controlbuf.go +++ b/go-controller/vendor/google.golang.org/grpc/internal/transport/controlbuf.go @@ -32,6 +32,7 @@ import ( "golang.org/x/net/http2/hpack" "google.golang.org/grpc/internal/grpclog" "google.golang.org/grpc/internal/grpcutil" + "google.golang.org/grpc/mem" "google.golang.org/grpc/status" ) @@ -148,9 +149,9 @@ type dataFrame struct { streamID uint32 endStream bool h []byte - d []byte + reader mem.Reader // onEachWrite is called every time - // a part of d is written out. + // a part of data is written out. onEachWrite func() } @@ -289,18 +290,22 @@ func (l *outStreamList) dequeue() *outStream { } // controlBuffer is a way to pass information to loopy. -// Information is passed as specific struct types called control frames. -// A control frame not only represents data, messages or headers to be sent out -// but can also be used to instruct loopy to update its internal state. -// It shouldn't be confused with an HTTP2 frame, although some of the control frames -// like dataFrame and headerFrame do go out on wire as HTTP2 frames. +// +// Information is passed as specific struct types called control frames. A +// control frame not only represents data, messages or headers to be sent out +// but can also be used to instruct loopy to update its internal state. It +// shouldn't be confused with an HTTP2 frame, although some of the control +// frames like dataFrame and headerFrame do go out on wire as HTTP2 frames. type controlBuffer struct { - ch chan struct{} - done <-chan struct{} + wakeupCh chan struct{} // Unblocks readers waiting for something to read. + done <-chan struct{} // Closed when the transport is done. + + // Mutex guards all the fields below, except trfChan which can be read + // atomically without holding mu. mu sync.Mutex - consumerWaiting bool - list *itemList - err error + consumerWaiting bool // True when readers are blocked waiting for new data. + closed bool // True when the controlbuf is finished. + list *itemList // List of queued control frames. // transportResponseFrames counts the number of queued items that represent // the response of an action initiated by the peer. trfChan is created @@ -308,47 +313,59 @@ type controlBuffer struct { // closed and nilled when transportResponseFrames drops below the // threshold. Both fields are protected by mu. transportResponseFrames int - trfChan atomic.Value // chan struct{} + trfChan atomic.Pointer[chan struct{}] } func newControlBuffer(done <-chan struct{}) *controlBuffer { return &controlBuffer{ - ch: make(chan struct{}, 1), - list: &itemList{}, - done: done, + wakeupCh: make(chan struct{}, 1), + list: &itemList{}, + done: done, } } -// throttle blocks if there are too many incomingSettings/cleanupStreams in the -// controlbuf. +// throttle blocks if there are too many frames in the control buf that +// represent the response of an action initiated by the peer, like +// incomingSettings cleanupStreams etc. func (c *controlBuffer) throttle() { - ch, _ := c.trfChan.Load().(chan struct{}) - if ch != nil { + if ch := c.trfChan.Load(); ch != nil { select { - case <-ch: + case <-(*ch): case <-c.done: } } } +// put adds an item to the controlbuf. func (c *controlBuffer) put(it cbItem) error { _, err := c.executeAndPut(nil, it) return err } +// executeAndPut runs f, and if the return value is true, adds the given item to +// the controlbuf. The item could be nil, in which case, this method simply +// executes f and does not add the item to the controlbuf. +// +// The first return value indicates whether the item was successfully added to +// the control buffer. A non-nil error, specifically ErrConnClosing, is returned +// if the control buffer is already closed. func (c *controlBuffer) executeAndPut(f func() bool, it cbItem) (bool, error) { - var wakeUp bool c.mu.Lock() - if c.err != nil { - c.mu.Unlock() - return false, c.err + defer c.mu.Unlock() + + if c.closed { + return false, ErrConnClosing } if f != nil { if !f() { // f wasn't successful - c.mu.Unlock() return false, nil } } + if it == nil { + return true, nil + } + + var wakeUp bool if c.consumerWaiting { wakeUp = true c.consumerWaiting = false @@ -359,98 +376,102 @@ func (c *controlBuffer) executeAndPut(f func() bool, it cbItem) (bool, error) { if c.transportResponseFrames == maxQueuedTransportResponseFrames { // We are adding the frame that puts us over the threshold; create // a throttling channel. - c.trfChan.Store(make(chan struct{})) + ch := make(chan struct{}) + c.trfChan.Store(&ch) } } - c.mu.Unlock() if wakeUp { select { - case c.ch <- struct{}{}: + case c.wakeupCh <- struct{}{}: default: } } return true, nil } -// Note argument f should never be nil. -func (c *controlBuffer) execute(f func(it any) bool, it any) (bool, error) { - c.mu.Lock() - if c.err != nil { - c.mu.Unlock() - return false, c.err - } - if !f(it) { // f wasn't successful - c.mu.Unlock() - return false, nil - } - c.mu.Unlock() - return true, nil -} - +// get returns the next control frame from the control buffer. If block is true +// **and** there are no control frames in the control buffer, the call blocks +// until one of the conditions is met: there is a frame to return or the +// transport is closed. func (c *controlBuffer) get(block bool) (any, error) { for { c.mu.Lock() - if c.err != nil { + frame, err := c.getOnceLocked() + if frame != nil || err != nil || !block { + // If we read a frame or an error, we can return to the caller. The + // call to getOnceLocked() returns a nil frame and a nil error if + // there is nothing to read, and in that case, if the caller asked + // us not to block, we can return now as well. c.mu.Unlock() - return nil, c.err - } - if !c.list.isEmpty() { - h := c.list.dequeue().(cbItem) - if h.isTransportResponseFrame() { - if c.transportResponseFrames == maxQueuedTransportResponseFrames { - // We are removing the frame that put us over the - // threshold; close and clear the throttling channel. - ch := c.trfChan.Load().(chan struct{}) - close(ch) - c.trfChan.Store((chan struct{})(nil)) - } - c.transportResponseFrames-- - } - c.mu.Unlock() - return h, nil - } - if !block { - c.mu.Unlock() - return nil, nil + return frame, err } c.consumerWaiting = true c.mu.Unlock() + + // Release the lock above and wait to be woken up. select { - case <-c.ch: + case <-c.wakeupCh: case <-c.done: return nil, errors.New("transport closed by client") } } } +// Callers must not use this method, but should instead use get(). +// +// Caller must hold c.mu. +func (c *controlBuffer) getOnceLocked() (any, error) { + if c.closed { + return false, ErrConnClosing + } + if c.list.isEmpty() { + return nil, nil + } + h := c.list.dequeue().(cbItem) + if h.isTransportResponseFrame() { + if c.transportResponseFrames == maxQueuedTransportResponseFrames { + // We are removing the frame that put us over the + // threshold; close and clear the throttling channel. + ch := c.trfChan.Swap(nil) + close(*ch) + } + c.transportResponseFrames-- + } + return h, nil +} + +// finish closes the control buffer, cleaning up any streams that have queued +// header frames. Once this method returns, no more frames can be added to the +// control buffer, and attempts to do so will return ErrConnClosing. func (c *controlBuffer) finish() { c.mu.Lock() - if c.err != nil { - c.mu.Unlock() + defer c.mu.Unlock() + + if c.closed { return } - c.err = ErrConnClosing + c.closed = true // There may be headers for streams in the control buffer. // These streams need to be cleaned out since the transport // is still not aware of these yet. for head := c.list.dequeueAll(); head != nil; head = head.next { - hdr, ok := head.it.(*headerFrame) - if !ok { - continue - } - if hdr.onOrphaned != nil { // It will be nil on the server-side. - hdr.onOrphaned(ErrConnClosing) + switch v := head.it.(type) { + case *headerFrame: + if v.onOrphaned != nil { // It will be nil on the server-side. + v.onOrphaned(ErrConnClosing) + } + case *dataFrame: + _ = v.reader.Close() } } + // In case throttle() is currently in flight, it needs to be unblocked. // Otherwise, the transport may not close, since the transport is closed by // the reader encountering the connection error. - ch, _ := c.trfChan.Load().(chan struct{}) + ch := c.trfChan.Swap(nil) if ch != nil { - close(ch) + close(*ch) } - c.trfChan.Store((chan struct{})(nil)) - c.mu.Unlock() } type side int @@ -466,7 +487,7 @@ const ( // stream maintains a queue of data frames; as loopy receives data frames // it gets added to the queue of the relevant stream. // Loopy goes over this list of active streams by processing one node every iteration, -// thereby closely resemebling to a round-robin scheduling over all streams. While +// thereby closely resembling a round-robin scheduling over all streams. While // processing a stream, loopy writes out data bytes from this stream capped by the min // of http2MaxFrameLen, connection-level flow control and stream-level flow control. type loopyWriter struct { @@ -490,12 +511,13 @@ type loopyWriter struct { draining bool conn net.Conn logger *grpclog.PrefixLogger + bufferPool mem.BufferPool // Side-specific handlers ssGoAwayHandler func(*goAway) (bool, error) } -func newLoopyWriter(s side, fr *framer, cbuf *controlBuffer, bdpEst *bdpEstimator, conn net.Conn, logger *grpclog.PrefixLogger, goAwayHandler func(*goAway) (bool, error)) *loopyWriter { +func newLoopyWriter(s side, fr *framer, cbuf *controlBuffer, bdpEst *bdpEstimator, conn net.Conn, logger *grpclog.PrefixLogger, goAwayHandler func(*goAway) (bool, error), bufferPool mem.BufferPool) *loopyWriter { var buf bytes.Buffer l := &loopyWriter{ side: s, @@ -511,6 +533,7 @@ func newLoopyWriter(s side, fr *framer, cbuf *controlBuffer, bdpEst *bdpEstimato conn: conn, logger: logger, ssGoAwayHandler: goAwayHandler, + bufferPool: bufferPool, } return l } @@ -768,6 +791,11 @@ func (l *loopyWriter) cleanupStreamHandler(c *cleanupStream) error { // not be established yet. delete(l.estdStreams, c.streamID) str.deleteSelf() + for head := str.itl.dequeueAll(); head != nil; head = head.next { + if df, ok := head.it.(*dataFrame); ok { + _ = df.reader.Close() + } + } } if c.rst { // If RST_STREAM needs to be sent. if err := l.framer.fr.WriteRSTStream(c.streamID, c.rstCode); err != nil { @@ -903,16 +931,18 @@ func (l *loopyWriter) processData() (bool, error) { dataItem := str.itl.peek().(*dataFrame) // Peek at the first data item this stream. // A data item is represented by a dataFrame, since it later translates into // multiple HTTP2 data frames. - // Every dataFrame has two buffers; h that keeps grpc-message header and d that is actual data. - // As an optimization to keep wire traffic low, data from d is copied to h to make as big as the - // maximum possible HTTP2 frame size. + // Every dataFrame has two buffers; h that keeps grpc-message header and data + // that is the actual message. As an optimization to keep wire traffic low, data + // from data is copied to h to make as big as the maximum possible HTTP2 frame + // size. - if len(dataItem.h) == 0 && len(dataItem.d) == 0 { // Empty data frame + if len(dataItem.h) == 0 && dataItem.reader.Remaining() == 0 { // Empty data frame // Client sends out empty data frame with endStream = true if err := l.framer.fr.WriteData(dataItem.streamID, dataItem.endStream, nil); err != nil { return false, err } str.itl.dequeue() // remove the empty data item from stream + _ = dataItem.reader.Close() if str.itl.isEmpty() { str.state = empty } else if trailer, ok := str.itl.peek().(*headerFrame); ok { // the next item is trailers. @@ -927,9 +957,7 @@ func (l *loopyWriter) processData() (bool, error) { } return false, nil } - var ( - buf []byte - ) + // Figure out the maximum size we can send maxSize := http2MaxFrameLen if strQuota := int(l.oiws) - str.bytesOutStanding; strQuota <= 0 { // stream-level flow control. @@ -943,43 +971,50 @@ func (l *loopyWriter) processData() (bool, error) { } // Compute how much of the header and data we can send within quota and max frame length hSize := min(maxSize, len(dataItem.h)) - dSize := min(maxSize-hSize, len(dataItem.d)) - if hSize != 0 { - if dSize == 0 { - buf = dataItem.h - } else { - // We can add some data to grpc message header to distribute bytes more equally across frames. - // Copy on the stack to avoid generating garbage - var localBuf [http2MaxFrameLen]byte - copy(localBuf[:hSize], dataItem.h) - copy(localBuf[hSize:], dataItem.d[:dSize]) - buf = localBuf[:hSize+dSize] - } + dSize := min(maxSize-hSize, dataItem.reader.Remaining()) + remainingBytes := len(dataItem.h) + dataItem.reader.Remaining() - hSize - dSize + size := hSize + dSize + + var buf *[]byte + + if hSize != 0 && dSize == 0 { + buf = &dataItem.h } else { - buf = dataItem.d - } + // Note: this is only necessary because the http2.Framer does not support + // partially writing a frame, so the sequence must be materialized into a buffer. + // TODO: Revisit once https://github.com/golang/go/issues/66655 is addressed. + pool := l.bufferPool + if pool == nil { + // Note that this is only supposed to be nil in tests. Otherwise, stream is + // always initialized with a BufferPool. + pool = mem.DefaultBufferPool() + } + buf = pool.Get(size) + defer pool.Put(buf) - size := hSize + dSize + copy((*buf)[:hSize], dataItem.h) + _, _ = dataItem.reader.Read((*buf)[hSize:]) + } // Now that outgoing flow controls are checked we can replenish str's write quota str.wq.replenish(size) var endStream bool // If this is the last data message on this stream and all of it can be written in this iteration. - if dataItem.endStream && len(dataItem.h)+len(dataItem.d) <= size { + if dataItem.endStream && remainingBytes == 0 { endStream = true } if dataItem.onEachWrite != nil { dataItem.onEachWrite() } - if err := l.framer.fr.WriteData(dataItem.streamID, endStream, buf[:size]); err != nil { + if err := l.framer.fr.WriteData(dataItem.streamID, endStream, (*buf)[:size]); err != nil { return false, err } str.bytesOutStanding += size l.sendQuota -= uint32(size) dataItem.h = dataItem.h[hSize:] - dataItem.d = dataItem.d[dSize:] - if len(dataItem.h) == 0 && len(dataItem.d) == 0 { // All the data from that message was written out. + if remainingBytes == 0 { // All the data from that message was written out. + _ = dataItem.reader.Close() str.itl.dequeue() } if str.itl.isEmpty() { @@ -998,10 +1033,3 @@ func (l *loopyWriter) processData() (bool, error) { } return false, nil } - -func min(a, b int) int { - if a < b { - return a - } - return b -} diff --git a/go-controller/vendor/google.golang.org/grpc/internal/transport/handler_server.go b/go-controller/vendor/google.golang.org/grpc/internal/transport/handler_server.go index 4a3ddce29a..ce878693bd 100644 --- a/go-controller/vendor/google.golang.org/grpc/internal/transport/handler_server.go +++ b/go-controller/vendor/google.golang.org/grpc/internal/transport/handler_server.go @@ -24,7 +24,6 @@ package transport import ( - "bytes" "context" "errors" "fmt" @@ -40,6 +39,7 @@ import ( "google.golang.org/grpc/credentials" "google.golang.org/grpc/internal/grpclog" "google.golang.org/grpc/internal/grpcutil" + "google.golang.org/grpc/mem" "google.golang.org/grpc/metadata" "google.golang.org/grpc/peer" "google.golang.org/grpc/stats" @@ -50,7 +50,7 @@ import ( // NewServerHandlerTransport returns a ServerTransport handling gRPC from // inside an http.Handler, or writes an HTTP error to w and returns an error. // It requires that the http Server supports HTTP/2. -func NewServerHandlerTransport(w http.ResponseWriter, r *http.Request, stats []stats.Handler) (ServerTransport, error) { +func NewServerHandlerTransport(w http.ResponseWriter, r *http.Request, stats []stats.Handler, bufferPool mem.BufferPool) (ServerTransport, error) { if r.Method != http.MethodPost { w.Header().Set("Allow", http.MethodPost) msg := fmt.Sprintf("invalid gRPC request method %q", r.Method) @@ -98,6 +98,7 @@ func NewServerHandlerTransport(w http.ResponseWriter, r *http.Request, stats []s contentType: contentType, contentSubtype: contentSubtype, stats: stats, + bufferPool: bufferPool, } st.logger = prefixLoggerForServerHandlerTransport(st) @@ -171,6 +172,8 @@ type serverHandlerTransport struct { stats []stats.Handler logger *grpclog.PrefixLogger + + bufferPool mem.BufferPool } func (ht *serverHandlerTransport) Close(err error) { @@ -244,6 +247,7 @@ func (ht *serverHandlerTransport) WriteStatus(s *Stream, st *status.Status) erro } s.hdrMu.Lock() + defer s.hdrMu.Unlock() if p := st.Proto(); p != nil && len(p.Details) > 0 { delete(s.trailer, grpcStatusDetailsBinHeader) stBytes, err := proto.Marshal(p) @@ -268,7 +272,6 @@ func (ht *serverHandlerTransport) WriteStatus(s *Stream, st *status.Status) erro } } } - s.hdrMu.Unlock() }) if err == nil { // transport has not been closed @@ -330,16 +333,28 @@ func (ht *serverHandlerTransport) writeCustomHeaders(s *Stream) { s.hdrMu.Unlock() } -func (ht *serverHandlerTransport) Write(s *Stream, hdr []byte, data []byte, opts *Options) error { +func (ht *serverHandlerTransport) Write(s *Stream, hdr []byte, data mem.BufferSlice, _ *Options) error { + // Always take a reference because otherwise there is no guarantee the data will + // be available after this function returns. This is what callers to Write + // expect. + data.Ref() headersWritten := s.updateHeaderSent() - return ht.do(func() { + err := ht.do(func() { + defer data.Free() if !headersWritten { ht.writePendingHeaders(s) } ht.rw.Write(hdr) - ht.rw.Write(data) + for _, b := range data { + _, _ = ht.rw.Write(b.ReadOnlyData()) + } ht.rw.(http.Flusher).Flush() }) + if err != nil { + data.Free() + return err + } + return nil } func (ht *serverHandlerTransport) WriteHeader(s *Stream, md metadata.MD) error { @@ -406,7 +421,7 @@ func (ht *serverHandlerTransport) HandleStreams(ctx context.Context, startStream headerWireLength: 0, // won't have access to header wire length until golang/go#18997. } s.trReader = &transportReader{ - reader: &recvBufferReader{ctx: s.ctx, ctxDone: s.ctx.Done(), recv: s.buf, freeBuffer: func(*bytes.Buffer) {}}, + reader: &recvBufferReader{ctx: s.ctx, ctxDone: s.ctx.Done(), recv: s.buf}, windowHandler: func(int) {}, } @@ -415,21 +430,19 @@ func (ht *serverHandlerTransport) HandleStreams(ctx context.Context, startStream go func() { defer close(readerDone) - // TODO: minimize garbage, optimize recvBuffer code/ownership - const readSize = 8196 - for buf := make([]byte, readSize); ; { - n, err := req.Body.Read(buf) + for { + buf := ht.bufferPool.Get(http2MaxFrameLen) + n, err := req.Body.Read(*buf) if n > 0 { - s.buf.put(recvMsg{buffer: bytes.NewBuffer(buf[:n:n])}) - buf = buf[n:] + *buf = (*buf)[:n] + s.buf.put(recvMsg{buffer: mem.NewBuffer(buf, ht.bufferPool)}) + } else { + ht.bufferPool.Put(buf) } if err != nil { s.buf.put(recvMsg{err: mapRecvMsgError(err)}) return } - if len(buf) == 0 { - buf = make([]byte, readSize) - } } }() @@ -462,7 +475,7 @@ func (ht *serverHandlerTransport) IncrMsgSent() {} func (ht *serverHandlerTransport) IncrMsgRecv() {} -func (ht *serverHandlerTransport) Drain(debugData string) { +func (ht *serverHandlerTransport) Drain(string) { panic("Drain() is not implemented") } diff --git a/go-controller/vendor/google.golang.org/grpc/internal/transport/http2_client.go b/go-controller/vendor/google.golang.org/grpc/internal/transport/http2_client.go index 3c63c70698..62b81885d8 100644 --- a/go-controller/vendor/google.golang.org/grpc/internal/transport/http2_client.go +++ b/go-controller/vendor/google.golang.org/grpc/internal/transport/http2_client.go @@ -47,6 +47,7 @@ import ( isyscall "google.golang.org/grpc/internal/syscall" "google.golang.org/grpc/internal/transport/networktype" "google.golang.org/grpc/keepalive" + "google.golang.org/grpc/mem" "google.golang.org/grpc/metadata" "google.golang.org/grpc/peer" "google.golang.org/grpc/resolver" @@ -59,6 +60,8 @@ import ( // atomically. var clientConnectionCounter uint64 +var goAwayLoopyWriterTimeout = 5 * time.Second + var metadataFromOutgoingContextRaw = internal.FromOutgoingContextRaw.(func(context.Context) (metadata.MD, [][]string, bool)) // http2Client implements the ClientTransport interface with HTTP2. @@ -83,9 +86,9 @@ type http2Client struct { writerDone chan struct{} // sync point to enable testing. // goAway is closed to notify the upper layer (i.e., addrConn.transportMonitor) // that the server sent GoAway on this transport. - goAway chan struct{} - - framer *framer + goAway chan struct{} + keepaliveDone chan struct{} // Closed when the keepalive goroutine exits. + framer *framer // controlBuf delivers all the control related tasks (e.g., window // updates, reset streams, and various settings) to the controller. // Do not access controlBuf with mu held. @@ -144,7 +147,7 @@ type http2Client struct { onClose func(GoAwayReason) - bufferPool *bufferPool + bufferPool mem.BufferPool connectionID uint64 logger *grpclog.PrefixLogger @@ -229,7 +232,7 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts } }(conn) - // The following defer and goroutine monitor the connectCtx for cancelation + // The following defer and goroutine monitor the connectCtx for cancellation // and deadline. On context expiration, the connection is hard closed and // this function will naturally fail as a result. Otherwise, the defer // waits for the goroutine to exit to prevent the context from being @@ -332,6 +335,7 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts readerDone: make(chan struct{}), writerDone: make(chan struct{}), goAway: make(chan struct{}), + keepaliveDone: make(chan struct{}), framer: newFramer(conn, writeBufSize, readBufSize, opts.SharedWriteBuffer, maxHeaderListSize), fc: &trInFlow{limit: uint32(icwz)}, scheme: scheme, @@ -346,7 +350,7 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts streamQuota: defaultMaxStreamsClient, streamsQuotaAvailable: make(chan struct{}, 1), keepaliveEnabled: keepaliveEnabled, - bufferPool: newBufferPool(), + bufferPool: opts.BufferPool, onClose: onClose, } var czSecurity credentials.ChannelzSecurityValue @@ -463,7 +467,7 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts return nil, err } go func() { - t.loopy = newLoopyWriter(clientSide, t.framer, t.controlBuf, t.bdpEst, t.conn, t.logger, t.outgoingGoAwayHandler) + t.loopy = newLoopyWriter(clientSide, t.framer, t.controlBuf, t.bdpEst, t.conn, t.logger, t.outgoingGoAwayHandler, t.bufferPool) if err := t.loopy.run(); !isIOError(err) { // Immediately close the connection, as the loopy writer returns // when there are no more active streams and we were draining (the @@ -504,7 +508,6 @@ func (t *http2Client) newStream(ctx context.Context, callHdr *CallHdr) *Stream { closeStream: func(err error) { t.CloseStream(s, err) }, - freeBuffer: t.bufferPool.put, }, windowHandler: func(n int) { t.updateWindow(s, uint32(n)) @@ -525,8 +528,9 @@ func (t *http2Client) getPeer() *peer.Peer { // to be the last frame loopy writes to the transport. func (t *http2Client) outgoingGoAwayHandler(g *goAway) (bool, error) { t.mu.Lock() - defer t.mu.Unlock() - if err := t.framer.fr.WriteGoAway(t.nextID-2, http2.ErrCodeNo, g.debugData); err != nil { + maxStreamID := t.nextID - 2 + t.mu.Unlock() + if err := t.framer.fr.WriteGoAway(maxStreamID, http2.ErrCodeNo, g.debugData); err != nil { return false, err } return false, g.closeConn @@ -770,7 +774,7 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (*Stream, hdr := &headerFrame{ hf: headerFields, endStream: false, - initStream: func(id uint32) error { + initStream: func(uint32) error { t.mu.Lock() // TODO: handle transport closure in loopy instead and remove this // initStream is never called when transport is draining. @@ -983,6 +987,7 @@ func (t *http2Client) closeStream(s *Stream, err error, rst bool, rstCode http2. // only once on a transport. Once it is called, the transport should not be // accessed anymore. func (t *http2Client) Close(err error) { + t.conn.SetWriteDeadline(time.Now().Add(time.Second * 10)) t.mu.Lock() // Make sure we only close once. if t.state == closing { @@ -1005,18 +1010,33 @@ func (t *http2Client) Close(err error) { // should unblock it so that the goroutine eventually exits. t.kpDormancyCond.Signal() } + // Append info about previous goaways if there were any, since this may be important + // for understanding the root cause for this connection to be closed. + goAwayDebugMessage := t.goAwayDebugMessage t.mu.Unlock() + // Per HTTP/2 spec, a GOAWAY frame must be sent before closing the - // connection. See https://httpwg.org/specs/rfc7540.html#GOAWAY. + // connection. See https://httpwg.org/specs/rfc7540.html#GOAWAY. It + // also waits for loopyWriter to be closed with a timer to avoid the + // long blocking in case the connection is blackholed, i.e. TCP is + // just stuck. t.controlBuf.put(&goAway{code: http2.ErrCodeNo, debugData: []byte("client transport shutdown"), closeConn: err}) - <-t.writerDone + timer := time.NewTimer(goAwayLoopyWriterTimeout) + defer timer.Stop() + select { + case <-t.writerDone: // success + case <-timer.C: + t.logger.Infof("Failed to write a GOAWAY frame as part of connection close after %s. Giving up and closing the transport.", goAwayLoopyWriterTimeout) + } t.cancel() t.conn.Close() + // Waits for the reader and keepalive goroutines to exit before returning to + // ensure all resources are cleaned up before Close can return. + <-t.readerDone + if t.keepaliveEnabled { + <-t.keepaliveDone + } channelz.RemoveEntry(t.channelz.ID) - // Append info about previous goaways if there were any, since this may be important - // for understanding the root cause for this connection to be closed. - _, goAwayDebugMessage := t.GetGoAwayReason() - var st *status.Status if len(goAwayDebugMessage) > 0 { st = status.Newf(codes.Unavailable, "closing transport due to: %v, received prior goaway: %v", err, goAwayDebugMessage) @@ -1065,27 +1085,36 @@ func (t *http2Client) GracefulClose() { // Write formats the data into HTTP2 data frame(s) and sends it out. The caller // should proceed only if Write returns nil. -func (t *http2Client) Write(s *Stream, hdr []byte, data []byte, opts *Options) error { +func (t *http2Client) Write(s *Stream, hdr []byte, data mem.BufferSlice, opts *Options) error { + reader := data.Reader() + if opts.Last { // If it's the last message, update stream state. if !s.compareAndSwapState(streamActive, streamWriteDone) { + _ = reader.Close() return errStreamDone } } else if s.getState() != streamActive { + _ = reader.Close() return errStreamDone } df := &dataFrame{ streamID: s.id, endStream: opts.Last, h: hdr, - d: data, + reader: reader, } - if hdr != nil || data != nil { // If it's not an empty data frame, check quota. - if err := s.wq.get(int32(len(hdr) + len(data))); err != nil { + if hdr != nil || df.reader.Remaining() != 0 { // If it's not an empty data frame, check quota. + if err := s.wq.get(int32(len(hdr) + df.reader.Remaining())); err != nil { + _ = reader.Close() return err } } - return t.controlBuf.put(df) + if err := t.controlBuf.put(df); err != nil { + _ = reader.Close() + return err + } + return nil } func (t *http2Client) getStream(f http2.Frame) *Stream { @@ -1190,10 +1219,13 @@ func (t *http2Client) handleData(f *http2.DataFrame) { // guarantee f.Data() is consumed before the arrival of next frame. // Can this copy be eliminated? if len(f.Data()) > 0 { - buffer := t.bufferPool.get() - buffer.Reset() - buffer.Write(f.Data()) - s.write(recvMsg{buffer: buffer}) + pool := t.bufferPool + if pool == nil { + // Note that this is only supposed to be nil in tests. Otherwise, stream is + // always initialized with a BufferPool. + pool = mem.DefaultBufferPool() + } + s.write(recvMsg{buffer: mem.Copy(f.Data(), pool)}) } } // The server has closed the stream without sending trailers. Record that @@ -1222,7 +1254,7 @@ func (t *http2Client) handleRSTStream(f *http2.RSTStreamFrame) { if statusCode == codes.Canceled { if d, ok := s.ctx.Deadline(); ok && !d.After(time.Now()) { // Our deadline was already exceeded, and that was likely the cause - // of this cancelation. Alter the status code accordingly. + // of this cancellation. Alter the status code accordingly. statusCode = codes.DeadlineExceeded } } @@ -1291,11 +1323,11 @@ func (t *http2Client) handlePing(f *http2.PingFrame) { t.controlBuf.put(pingAck) } -func (t *http2Client) handleGoAway(f *http2.GoAwayFrame) { +func (t *http2Client) handleGoAway(f *http2.GoAwayFrame) error { t.mu.Lock() if t.state == closing { t.mu.Unlock() - return + return nil } if f.ErrCode == http2.ErrCodeEnhanceYourCalm && string(f.DebugData()) == "too_many_pings" { // When a client receives a GOAWAY with error code ENHANCE_YOUR_CALM and debug @@ -1307,8 +1339,7 @@ func (t *http2Client) handleGoAway(f *http2.GoAwayFrame) { id := f.LastStreamID if id > 0 && id%2 == 0 { t.mu.Unlock() - t.Close(connectionErrorf(true, nil, "received goaway with non-zero even-numbered numbered stream id: %v", id)) - return + return connectionErrorf(true, nil, "received goaway with non-zero even-numbered stream id: %v", id) } // A client can receive multiple GoAways from the server (see // https://github.com/grpc/grpc-go/issues/1387). The idea is that the first @@ -1325,8 +1356,7 @@ func (t *http2Client) handleGoAway(f *http2.GoAwayFrame) { // If there are multiple GoAways the first one should always have an ID greater than the following ones. if id > t.prevGoAwayID { t.mu.Unlock() - t.Close(connectionErrorf(true, nil, "received goaway with stream id: %v, which exceeds stream id of previous goaway: %v", id, t.prevGoAwayID)) - return + return connectionErrorf(true, nil, "received goaway with stream id: %v, which exceeds stream id of previous goaway: %v", id, t.prevGoAwayID) } default: t.setGoAwayReason(f) @@ -1350,8 +1380,7 @@ func (t *http2Client) handleGoAway(f *http2.GoAwayFrame) { t.prevGoAwayID = id if len(t.activeStreams) == 0 { t.mu.Unlock() - t.Close(connectionErrorf(true, nil, "received goaway and there are no active streams")) - return + return connectionErrorf(true, nil, "received goaway and there are no active streams") } streamsToClose := make([]*Stream, 0) @@ -1368,6 +1397,7 @@ func (t *http2Client) handleGoAway(f *http2.GoAwayFrame) { for _, stream := range streamsToClose { t.closeStream(stream, errStreamDrain, false, http2.ErrCodeNo, statusGoAway, nil, false) } + return nil } // setGoAwayReason sets the value of t.goAwayReason based @@ -1603,7 +1633,13 @@ func (t *http2Client) readServerPreface() error { // network connection. If the server preface is not read successfully, an // error is pushed to errCh; otherwise errCh is closed with no error. func (t *http2Client) reader(errCh chan<- error) { - defer close(t.readerDone) + var errClose error + defer func() { + close(t.readerDone) + if errClose != nil { + t.Close(errClose) + } + }() if err := t.readServerPreface(); err != nil { errCh <- err @@ -1642,11 +1678,10 @@ func (t *http2Client) reader(errCh chan<- error) { t.closeStream(s, status.Error(code, msg), true, http2.ErrCodeProtocol, status.New(code, msg), nil, false) } continue - } else { - // Transport error. - t.Close(connectionErrorf(true, err, "error reading from server: %v", err)) - return } + // Transport error. + errClose = connectionErrorf(true, err, "error reading from server: %v", err) + return } switch frame := frame.(type) { case *http2.MetaHeadersFrame: @@ -1660,7 +1695,7 @@ func (t *http2Client) reader(errCh chan<- error) { case *http2.PingFrame: t.handlePing(frame) case *http2.GoAwayFrame: - t.handleGoAway(frame) + errClose = t.handleGoAway(frame) case *http2.WindowUpdateFrame: t.handleWindowUpdate(frame) default: @@ -1671,15 +1706,15 @@ func (t *http2Client) reader(errCh chan<- error) { } } -func minTime(a, b time.Duration) time.Duration { - if a < b { - return a - } - return b -} - // keepalive running in a separate goroutine makes sure the connection is alive by sending pings. func (t *http2Client) keepalive() { + var err error + defer func() { + close(t.keepaliveDone) + if err != nil { + t.Close(err) + } + }() p := &ping{data: [8]byte{}} // True iff a ping has been sent, and no data has been received since then. outstandingPing := false @@ -1703,7 +1738,7 @@ func (t *http2Client) keepalive() { continue } if outstandingPing && timeoutLeft <= 0 { - t.Close(connectionErrorf(true, nil, "keepalive ping failed to receive ACK within timeout")) + err = connectionErrorf(true, nil, "keepalive ping failed to receive ACK within timeout") return } t.mu.Lock() @@ -1745,7 +1780,7 @@ func (t *http2Client) keepalive() { // timeoutLeft. This will ensure that we wait only for kp.Time // before sending out the next ping (for cases where the ping is // acked). - sleepDuration := minTime(t.kp.Time, timeoutLeft) + sleepDuration := min(t.kp.Time, timeoutLeft) timeoutLeft -= sleepDuration timer.Reset(sleepDuration) case <-t.ctx.Done(): diff --git a/go-controller/vendor/google.golang.org/grpc/internal/transport/http2_server.go b/go-controller/vendor/google.golang.org/grpc/internal/transport/http2_server.go index b7091165b5..584b50fe55 100644 --- a/go-controller/vendor/google.golang.org/grpc/internal/transport/http2_server.go +++ b/go-controller/vendor/google.golang.org/grpc/internal/transport/http2_server.go @@ -39,6 +39,7 @@ import ( "google.golang.org/grpc/internal/grpcutil" "google.golang.org/grpc/internal/pretty" "google.golang.org/grpc/internal/syscall" + "google.golang.org/grpc/mem" "google.golang.org/protobuf/proto" "google.golang.org/grpc/codes" @@ -119,7 +120,7 @@ type http2Server struct { // Fields below are for channelz metric collection. channelz *channelz.Socket - bufferPool *bufferPool + bufferPool mem.BufferPool connectionID uint64 @@ -261,7 +262,7 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport, idle: time.Now(), kep: kep, initialWindowSize: iwz, - bufferPool: newBufferPool(), + bufferPool: config.BufferPool, } var czSecurity credentials.ChannelzSecurityValue if au, ok := authInfo.(credentials.ChannelzSecurityInfo); ok { @@ -330,7 +331,7 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport, t.handleSettings(sf) go func() { - t.loopy = newLoopyWriter(serverSide, t.framer, t.controlBuf, t.bdpEst, t.conn, t.logger, t.outgoingGoAwayHandler) + t.loopy = newLoopyWriter(serverSide, t.framer, t.controlBuf, t.bdpEst, t.conn, t.logger, t.outgoingGoAwayHandler, t.bufferPool) err := t.loopy.run() close(t.loopyWriterDone) if !isIOError(err) { @@ -613,10 +614,9 @@ func (t *http2Server) operateHeaders(ctx context.Context, frame *http2.MetaHeade s.wq = newWriteQuota(defaultWriteQuota, s.ctxDone) s.trReader = &transportReader{ reader: &recvBufferReader{ - ctx: s.ctx, - ctxDone: s.ctxDone, - recv: s.buf, - freeBuffer: t.bufferPool.put, + ctx: s.ctx, + ctxDone: s.ctxDone, + recv: s.buf, }, windowHandler: func(n int) { t.updateWindow(s, uint32(n)) @@ -813,10 +813,13 @@ func (t *http2Server) handleData(f *http2.DataFrame) { // guarantee f.Data() is consumed before the arrival of next frame. // Can this copy be eliminated? if len(f.Data()) > 0 { - buffer := t.bufferPool.get() - buffer.Reset() - buffer.Write(f.Data()) - s.write(recvMsg{buffer: buffer}) + pool := t.bufferPool + if pool == nil { + // Note that this is only supposed to be nil in tests. Otherwise, stream is + // always initialized with a BufferPool. + pool = mem.DefaultBufferPool() + } + s.write(recvMsg{buffer: mem.Copy(f.Data(), pool)}) } } if f.StreamEnded() { @@ -1089,7 +1092,9 @@ func (t *http2Server) WriteStatus(s *Stream, st *status.Status) error { onWrite: t.setResetPingStrikes, } - success, err := t.controlBuf.execute(t.checkForHeaderListSize, trailingHeader) + success, err := t.controlBuf.executeAndPut(func() bool { + return t.checkForHeaderListSize(trailingHeader) + }, nil) if !success { if err != nil { return err @@ -1112,27 +1117,37 @@ func (t *http2Server) WriteStatus(s *Stream, st *status.Status) error { // Write converts the data into HTTP2 data frame and sends it out. Non-nil error // is returns if it fails (e.g., framing error, transport error). -func (t *http2Server) Write(s *Stream, hdr []byte, data []byte, opts *Options) error { +func (t *http2Server) Write(s *Stream, hdr []byte, data mem.BufferSlice, _ *Options) error { + reader := data.Reader() + if !s.isHeaderSent() { // Headers haven't been written yet. if err := t.WriteHeader(s, nil); err != nil { + _ = reader.Close() return err } } else { // Writing headers checks for this condition. if s.getState() == streamDone { + _ = reader.Close() return t.streamContextErr(s) } } + df := &dataFrame{ streamID: s.id, h: hdr, - d: data, + reader: reader, onEachWrite: t.setResetPingStrikes, } - if err := s.wq.get(int32(len(hdr) + len(data))); err != nil { + if err := s.wq.get(int32(len(hdr) + df.reader.Remaining())); err != nil { + _ = reader.Close() return t.streamContextErr(s) } - return t.controlBuf.put(df) + if err := t.controlBuf.put(df); err != nil { + _ = reader.Close() + return err + } + return nil } // keepalive running in a separate goroutine does the following: @@ -1223,7 +1238,7 @@ func (t *http2Server) keepalive() { // timeoutLeft. This will ensure that we wait only for kp.Time // before sending out the next ping (for cases where the ping is // acked). - sleepDuration := minTime(t.kp.Time, kpTimeoutLeft) + sleepDuration := min(t.kp.Time, kpTimeoutLeft) kpTimeoutLeft -= sleepDuration kpTimer.Reset(sleepDuration) case <-t.done: diff --git a/go-controller/vendor/google.golang.org/grpc/internal/transport/http_util.go b/go-controller/vendor/google.golang.org/grpc/internal/transport/http_util.go index 39cef3bd44..3613d7b648 100644 --- a/go-controller/vendor/google.golang.org/grpc/internal/transport/http_util.go +++ b/go-controller/vendor/google.golang.org/grpc/internal/transport/http_util.go @@ -317,28 +317,32 @@ func newBufWriter(conn net.Conn, batchSize int, pool *sync.Pool) *bufWriter { return w } -func (w *bufWriter) Write(b []byte) (n int, err error) { +func (w *bufWriter) Write(b []byte) (int, error) { if w.err != nil { return 0, w.err } if w.batchSize == 0 { // Buffer has been disabled. - n, err = w.conn.Write(b) + n, err := w.conn.Write(b) return n, toIOError(err) } if w.buf == nil { b := w.pool.Get().(*[]byte) w.buf = *b } + written := 0 for len(b) > 0 { - nn := copy(w.buf[w.offset:], b) - b = b[nn:] - w.offset += nn - n += nn - if w.offset >= w.batchSize { - err = w.flushKeepBuffer() + copied := copy(w.buf[w.offset:], b) + b = b[copied:] + written += copied + w.offset += copied + if w.offset < w.batchSize { + continue + } + if err := w.flushKeepBuffer(); err != nil { + return written, err } } - return n, err + return written, nil } func (w *bufWriter) Flush() error { @@ -389,7 +393,7 @@ type framer struct { fr *http2.Framer } -var writeBufferPoolMap map[int]*sync.Pool = make(map[int]*sync.Pool) +var writeBufferPoolMap = make(map[int]*sync.Pool) var writeBufferMutex sync.Mutex func newFramer(conn net.Conn, writeBufferSize, readBufferSize int, sharedWriteBuffer bool, maxHeaderListSize uint32) *framer { diff --git a/go-controller/vendor/google.golang.org/grpc/internal/transport/proxy.go b/go-controller/vendor/google.golang.org/grpc/internal/transport/proxy.go index 24fa103257..54b2244365 100644 --- a/go-controller/vendor/google.golang.org/grpc/internal/transport/proxy.go +++ b/go-controller/vendor/google.golang.org/grpc/internal/transport/proxy.go @@ -107,8 +107,14 @@ func doHTTPConnectHandshake(ctx context.Context, conn net.Conn, backendAddr stri } return nil, fmt.Errorf("failed to do connect handshake, response: %q", dump) } - - return &bufConn{Conn: conn, r: r}, nil + // The buffer could contain extra bytes from the target server, so we can't + // discard it. However, in many cases where the server waits for the client + // to send the first message (e.g. when TLS is being used), the buffer will + // be empty, so we can avoid the overhead of reading through this buffer. + if r.Buffered() != 0 { + return &bufConn{Conn: conn, r: r}, nil + } + return conn, nil } // proxyDial dials, connecting to a proxy first if necessary. Checks if a proxy diff --git a/go-controller/vendor/google.golang.org/grpc/internal/transport/transport.go b/go-controller/vendor/google.golang.org/grpc/internal/transport/transport.go index 4b39c0ade9..e12cb0bc91 100644 --- a/go-controller/vendor/google.golang.org/grpc/internal/transport/transport.go +++ b/go-controller/vendor/google.golang.org/grpc/internal/transport/transport.go @@ -22,7 +22,6 @@ package transport import ( - "bytes" "context" "errors" "fmt" @@ -37,6 +36,7 @@ import ( "google.golang.org/grpc/credentials" "google.golang.org/grpc/internal/channelz" "google.golang.org/grpc/keepalive" + "google.golang.org/grpc/mem" "google.golang.org/grpc/metadata" "google.golang.org/grpc/peer" "google.golang.org/grpc/resolver" @@ -47,32 +47,10 @@ import ( const logLevel = 2 -type bufferPool struct { - pool sync.Pool -} - -func newBufferPool() *bufferPool { - return &bufferPool{ - pool: sync.Pool{ - New: func() any { - return new(bytes.Buffer) - }, - }, - } -} - -func (p *bufferPool) get() *bytes.Buffer { - return p.pool.Get().(*bytes.Buffer) -} - -func (p *bufferPool) put(b *bytes.Buffer) { - p.pool.Put(b) -} - // recvMsg represents the received msg from the transport. All transport // protocol specific info has been removed. type recvMsg struct { - buffer *bytes.Buffer + buffer mem.Buffer // nil: received some data // io.EOF: stream is completed. data is nil. // other non-nil error: transport failure. data is nil. @@ -102,6 +80,9 @@ func newRecvBuffer() *recvBuffer { func (b *recvBuffer) put(r recvMsg) { b.mu.Lock() if b.err != nil { + // drop the buffer on the floor. Since b.err is not nil, any subsequent reads + // will always return an error, making this buffer inaccessible. + r.buffer.Free() b.mu.Unlock() // An error had occurred earlier, don't accept more // data or errors. @@ -148,45 +129,97 @@ type recvBufferReader struct { ctx context.Context ctxDone <-chan struct{} // cache of ctx.Done() (for performance). recv *recvBuffer - last *bytes.Buffer // Stores the remaining data in the previous calls. + last mem.Buffer // Stores the remaining data in the previous calls. err error - freeBuffer func(*bytes.Buffer) } -// Read reads the next len(p) bytes from last. If last is drained, it tries to -// read additional data from recv. It blocks if there no additional data available -// in recv. If Read returns any non-nil error, it will continue to return that error. -func (r *recvBufferReader) Read(p []byte) (n int, err error) { +func (r *recvBufferReader) ReadHeader(header []byte) (n int, err error) { if r.err != nil { return 0, r.err } if r.last != nil { - // Read remaining data left in last call. - copied, _ := r.last.Read(p) - if r.last.Len() == 0 { - r.freeBuffer(r.last) + n, r.last = mem.ReadUnsafe(header, r.last) + return n, nil + } + if r.closeStream != nil { + n, r.err = r.readHeaderClient(header) + } else { + n, r.err = r.readHeader(header) + } + return n, r.err +} + +// Read reads the next n bytes from last. If last is drained, it tries to read +// additional data from recv. It blocks if there no additional data available in +// recv. If Read returns any non-nil error, it will continue to return that +// error. +func (r *recvBufferReader) Read(n int) (buf mem.Buffer, err error) { + if r.err != nil { + return nil, r.err + } + if r.last != nil { + buf = r.last + if r.last.Len() > n { + buf, r.last = mem.SplitUnsafe(buf, n) + } else { r.last = nil } - return copied, nil + return buf, nil } if r.closeStream != nil { - n, r.err = r.readClient(p) + buf, r.err = r.readClient(n) } else { - n, r.err = r.read(p) + buf, r.err = r.read(n) } - return n, r.err + return buf, r.err } -func (r *recvBufferReader) read(p []byte) (n int, err error) { +func (r *recvBufferReader) readHeader(header []byte) (n int, err error) { select { case <-r.ctxDone: return 0, ContextErr(r.ctx.Err()) case m := <-r.recv.get(): - return r.readAdditional(m, p) + return r.readHeaderAdditional(m, header) + } +} + +func (r *recvBufferReader) read(n int) (buf mem.Buffer, err error) { + select { + case <-r.ctxDone: + return nil, ContextErr(r.ctx.Err()) + case m := <-r.recv.get(): + return r.readAdditional(m, n) + } +} + +func (r *recvBufferReader) readHeaderClient(header []byte) (n int, err error) { + // If the context is canceled, then closes the stream with nil metadata. + // closeStream writes its error parameter to r.recv as a recvMsg. + // r.readAdditional acts on that message and returns the necessary error. + select { + case <-r.ctxDone: + // Note that this adds the ctx error to the end of recv buffer, and + // reads from the head. This will delay the error until recv buffer is + // empty, thus will delay ctx cancellation in Recv(). + // + // It's done this way to fix a race between ctx cancel and trailer. The + // race was, stream.Recv() may return ctx error if ctxDone wins the + // race, but stream.Trailer() may return a non-nil md because the stream + // was not marked as done when trailer is received. This closeStream + // call will mark stream as done, thus fix the race. + // + // TODO: delaying ctx error seems like a unnecessary side effect. What + // we really want is to mark the stream as done, and return ctx error + // faster. + r.closeStream(ContextErr(r.ctx.Err())) + m := <-r.recv.get() + return r.readHeaderAdditional(m, header) + case m := <-r.recv.get(): + return r.readHeaderAdditional(m, header) } } -func (r *recvBufferReader) readClient(p []byte) (n int, err error) { +func (r *recvBufferReader) readClient(n int) (buf mem.Buffer, err error) { // If the context is canceled, then closes the stream with nil metadata. // closeStream writes its error parameter to r.recv as a recvMsg. // r.readAdditional acts on that message and returns the necessary error. @@ -207,25 +240,40 @@ func (r *recvBufferReader) readClient(p []byte) (n int, err error) { // faster. r.closeStream(ContextErr(r.ctx.Err())) m := <-r.recv.get() - return r.readAdditional(m, p) + return r.readAdditional(m, n) case m := <-r.recv.get(): - return r.readAdditional(m, p) + return r.readAdditional(m, n) } } -func (r *recvBufferReader) readAdditional(m recvMsg, p []byte) (n int, err error) { +func (r *recvBufferReader) readHeaderAdditional(m recvMsg, header []byte) (n int, err error) { r.recv.load() if m.err != nil { + if m.buffer != nil { + m.buffer.Free() + } return 0, m.err } - copied, _ := m.buffer.Read(p) - if m.buffer.Len() == 0 { - r.freeBuffer(m.buffer) - r.last = nil - } else { - r.last = m.buffer + + n, r.last = mem.ReadUnsafe(header, m.buffer) + + return n, nil +} + +func (r *recvBufferReader) readAdditional(m recvMsg, n int) (b mem.Buffer, err error) { + r.recv.load() + if m.err != nil { + if m.buffer != nil { + m.buffer.Free() + } + return nil, m.err + } + + if m.buffer.Len() > n { + m.buffer, r.last = mem.SplitUnsafe(m.buffer, n) } - return copied, nil + + return m.buffer, nil } type streamState uint32 @@ -241,7 +289,7 @@ const ( type Stream struct { id uint32 st ServerTransport // nil for client side Stream - ct *http2Client // nil for server side Stream + ct ClientTransport // nil for server side Stream ctx context.Context // the associated context of the stream cancel context.CancelFunc // always nil for client side Stream done chan struct{} // closed at the end of stream to unblock writers. On the client side. @@ -251,7 +299,7 @@ type Stream struct { recvCompress string sendCompress string buf *recvBuffer - trReader io.Reader + trReader *transportReader fc *inFlow wq *writeQuota @@ -408,7 +456,7 @@ func (s *Stream) TrailersOnly() bool { return s.noHeaders } -// Trailer returns the cached trailer metedata. Note that if it is not called +// Trailer returns the cached trailer metadata. Note that if it is not called // after the entire stream is done, it could return an empty MD. Client // side only. // It can be safely read only after stream has ended that is either read @@ -499,36 +547,96 @@ func (s *Stream) write(m recvMsg) { s.buf.put(m) } -// Read reads all p bytes from the wire for this stream. -func (s *Stream) Read(p []byte) (n int, err error) { +// ReadHeader reads data into the provided header slice from the stream. It +// first checks if there was an error during a previous read operation and +// returns it if present. It then requests a read operation for the length of +// the header. It continues to read from the stream until the entire header +// slice is filled or an error occurs. If an `io.EOF` error is encountered +// with partially read data, it is converted to `io.ErrUnexpectedEOF` to +// indicate an unexpected end of the stream. The method returns any error +// encountered during the read process or nil if the header was successfully +// read. +func (s *Stream) ReadHeader(header []byte) (err error) { + // Don't request a read if there was an error earlier + if er := s.trReader.er; er != nil { + return er + } + s.requestRead(len(header)) + for len(header) != 0 { + n, err := s.trReader.ReadHeader(header) + header = header[n:] + if len(header) == 0 { + err = nil + } + if err != nil { + if n > 0 && err == io.EOF { + err = io.ErrUnexpectedEOF + } + return err + } + } + return nil +} + +// Read reads n bytes from the wire for this stream. +func (s *Stream) Read(n int) (data mem.BufferSlice, err error) { // Don't request a read if there was an error earlier - if er := s.trReader.(*transportReader).er; er != nil { - return 0, er + if er := s.trReader.er; er != nil { + return nil, er } - s.requestRead(len(p)) - return io.ReadFull(s.trReader, p) + s.requestRead(n) + for n != 0 { + buf, err := s.trReader.Read(n) + var bufLen int + if buf != nil { + bufLen = buf.Len() + } + n -= bufLen + if n == 0 { + err = nil + } + if err != nil { + if bufLen > 0 && err == io.EOF { + err = io.ErrUnexpectedEOF + } + data.Free() + return nil, err + } + data = append(data, buf) + } + return data, nil } -// tranportReader reads all the data available for this Stream from the transport and +// transportReader reads all the data available for this Stream from the transport and // passes them into the decoder, which converts them into a gRPC message stream. // The error is io.EOF when the stream is done or another non-nil error if // the stream broke. type transportReader struct { - reader io.Reader + reader *recvBufferReader // The handler to control the window update procedure for both this // particular stream and the associated transport. windowHandler func(int) er error } -func (t *transportReader) Read(p []byte) (n int, err error) { - n, err = t.reader.Read(p) +func (t *transportReader) ReadHeader(header []byte) (int, error) { + n, err := t.reader.ReadHeader(header) if err != nil { t.er = err - return + return 0, err } t.windowHandler(n) - return + return n, nil +} + +func (t *transportReader) Read(n int) (mem.Buffer, error) { + buf, err := t.reader.Read(n) + if err != nil { + t.er = err + return buf, err + } + t.windowHandler(buf.Len()) + return buf, nil } // BytesReceived indicates whether any bytes have been received on this stream. @@ -574,6 +682,7 @@ type ServerConfig struct { ChannelzParent *channelz.Server MaxHeaderListSize *uint32 HeaderTableSize *uint32 + BufferPool mem.BufferPool } // ConnectOptions covers all relevant options for communicating with the server. @@ -612,6 +721,8 @@ type ConnectOptions struct { MaxHeaderListSize *uint32 // UseProxy specifies if a proxy should be used. UseProxy bool + // The mem.BufferPool to use when reading/writing to the wire. + BufferPool mem.BufferPool } // NewClientTransport establishes the transport with the required ConnectOptions @@ -673,7 +784,7 @@ type ClientTransport interface { // Write sends the data for the given stream. A nil stream indicates // the write is to be performed on the transport as a whole. - Write(s *Stream, hdr []byte, data []byte, opts *Options) error + Write(s *Stream, hdr []byte, data mem.BufferSlice, opts *Options) error // NewStream creates a Stream for an RPC. NewStream(ctx context.Context, callHdr *CallHdr) (*Stream, error) @@ -725,7 +836,7 @@ type ServerTransport interface { // Write sends the data for the given stream. // Write may not be called on all streams. - Write(s *Stream, hdr []byte, data []byte, opts *Options) error + Write(s *Stream, hdr []byte, data mem.BufferSlice, opts *Options) error // WriteStatus sends the status of a stream to the client. WriteStatus is // the final call made on a stream and always occurs. @@ -798,7 +909,7 @@ var ( // connection is draining. This could be caused by goaway or balancer // removing the address. errStreamDrain = status.Error(codes.Unavailable, "the connection is draining") - // errStreamDone is returned from write at the client side to indiacte application + // errStreamDone is returned from write at the client side to indicate application // layer of an error. errStreamDone = errors.New("the stream is done") // StatusGoAway indicates that the server sent a GOAWAY that included this diff --git a/go-controller/vendor/google.golang.org/grpc/keepalive/keepalive.go b/go-controller/vendor/google.golang.org/grpc/keepalive/keepalive.go index 34d31b5e7d..eb42b19fb9 100644 --- a/go-controller/vendor/google.golang.org/grpc/keepalive/keepalive.go +++ b/go-controller/vendor/google.golang.org/grpc/keepalive/keepalive.go @@ -34,15 +34,29 @@ type ClientParameters struct { // After a duration of this time if the client doesn't see any activity it // pings the server to see if the transport is still alive. // If set below 10s, a minimum value of 10s will be used instead. - Time time.Duration // The current default value is infinity. + // + // Note that gRPC servers have a default EnforcementPolicy.MinTime of 5 + // minutes (which means the client shouldn't ping more frequently than every + // 5 minutes). + // + // Though not ideal, it's not a strong requirement for Time to be less than + // EnforcementPolicy.MinTime. Time will automatically double if the server + // disconnects due to its enforcement policy. + // + // For more details, see + // https://github.com/grpc/proposal/blob/master/A8-client-side-keepalive.md + Time time.Duration // After having pinged for keepalive check, the client waits for a duration // of Timeout and if no activity is seen even after that the connection is // closed. - Timeout time.Duration // The current default value is 20 seconds. + // + // If keepalive is enabled, and this value is not explicitly set, the default + // is 20 seconds. + Timeout time.Duration // If true, client sends keepalive pings even with no active RPCs. If false, // when there are no active RPCs, Time and Timeout will be ignored and no // keepalive pings will be sent. - PermitWithoutStream bool // false by default. + PermitWithoutStream bool } // ServerParameters is used to set keepalive and max-age parameters on the diff --git a/go-controller/vendor/google.golang.org/grpc/mem/buffer_pool.go b/go-controller/vendor/google.golang.org/grpc/mem/buffer_pool.go new file mode 100644 index 0000000000..c37c58c023 --- /dev/null +++ b/go-controller/vendor/google.golang.org/grpc/mem/buffer_pool.go @@ -0,0 +1,194 @@ +/* + * + * Copyright 2024 gRPC authors. + * + * 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 mem + +import ( + "sort" + "sync" + + "google.golang.org/grpc/internal" +) + +// BufferPool is a pool of buffers that can be shared and reused, resulting in +// decreased memory allocation. +type BufferPool interface { + // Get returns a buffer with specified length from the pool. + Get(length int) *[]byte + + // Put returns a buffer to the pool. + Put(*[]byte) +} + +var defaultBufferPoolSizes = []int{ + 256, + 4 << 10, // 4KB (go page size) + 16 << 10, // 16KB (max HTTP/2 frame size used by gRPC) + 32 << 10, // 32KB (default buffer size for io.Copy) + 1 << 20, // 1MB +} + +var defaultBufferPool BufferPool + +func init() { + defaultBufferPool = NewTieredBufferPool(defaultBufferPoolSizes...) + + internal.SetDefaultBufferPoolForTesting = func(pool BufferPool) { + defaultBufferPool = pool + } + + internal.SetBufferPoolingThresholdForTesting = func(threshold int) { + bufferPoolingThreshold = threshold + } +} + +// DefaultBufferPool returns the current default buffer pool. It is a BufferPool +// created with NewBufferPool that uses a set of default sizes optimized for +// expected workflows. +func DefaultBufferPool() BufferPool { + return defaultBufferPool +} + +// NewTieredBufferPool returns a BufferPool implementation that uses multiple +// underlying pools of the given pool sizes. +func NewTieredBufferPool(poolSizes ...int) BufferPool { + sort.Ints(poolSizes) + pools := make([]*sizedBufferPool, len(poolSizes)) + for i, s := range poolSizes { + pools[i] = newSizedBufferPool(s) + } + return &tieredBufferPool{ + sizedPools: pools, + } +} + +// tieredBufferPool implements the BufferPool interface with multiple tiers of +// buffer pools for different sizes of buffers. +type tieredBufferPool struct { + sizedPools []*sizedBufferPool + fallbackPool simpleBufferPool +} + +func (p *tieredBufferPool) Get(size int) *[]byte { + return p.getPool(size).Get(size) +} + +func (p *tieredBufferPool) Put(buf *[]byte) { + p.getPool(cap(*buf)).Put(buf) +} + +func (p *tieredBufferPool) getPool(size int) BufferPool { + poolIdx := sort.Search(len(p.sizedPools), func(i int) bool { + return p.sizedPools[i].defaultSize >= size + }) + + if poolIdx == len(p.sizedPools) { + return &p.fallbackPool + } + + return p.sizedPools[poolIdx] +} + +// sizedBufferPool is a BufferPool implementation that is optimized for specific +// buffer sizes. For example, HTTP/2 frames within gRPC have a default max size +// of 16kb and a sizedBufferPool can be configured to only return buffers with a +// capacity of 16kb. Note that however it does not support returning larger +// buffers and in fact panics if such a buffer is requested. Because of this, +// this BufferPool implementation is not meant to be used on its own and rather +// is intended to be embedded in a tieredBufferPool such that Get is only +// invoked when the required size is smaller than or equal to defaultSize. +type sizedBufferPool struct { + pool sync.Pool + defaultSize int +} + +func (p *sizedBufferPool) Get(size int) *[]byte { + buf := p.pool.Get().(*[]byte) + b := *buf + clear(b[:cap(b)]) + *buf = b[:size] + return buf +} + +func (p *sizedBufferPool) Put(buf *[]byte) { + if cap(*buf) < p.defaultSize { + // Ignore buffers that are too small to fit in the pool. Otherwise, when + // Get is called it will panic as it tries to index outside the bounds + // of the buffer. + return + } + p.pool.Put(buf) +} + +func newSizedBufferPool(size int) *sizedBufferPool { + return &sizedBufferPool{ + pool: sync.Pool{ + New: func() any { + buf := make([]byte, size) + return &buf + }, + }, + defaultSize: size, + } +} + +var _ BufferPool = (*simpleBufferPool)(nil) + +// simpleBufferPool is an implementation of the BufferPool interface that +// attempts to pool buffers with a sync.Pool. When Get is invoked, it tries to +// acquire a buffer from the pool but if that buffer is too small, it returns it +// to the pool and creates a new one. +type simpleBufferPool struct { + pool sync.Pool +} + +func (p *simpleBufferPool) Get(size int) *[]byte { + bs, ok := p.pool.Get().(*[]byte) + if ok && cap(*bs) >= size { + *bs = (*bs)[:size] + return bs + } + + // A buffer was pulled from the pool, but it is too small. Put it back in + // the pool and create one large enough. + if ok { + p.pool.Put(bs) + } + + b := make([]byte, size) + return &b +} + +func (p *simpleBufferPool) Put(buf *[]byte) { + p.pool.Put(buf) +} + +var _ BufferPool = NopBufferPool{} + +// NopBufferPool is a buffer pool that returns new buffers without pooling. +type NopBufferPool struct{} + +// Get returns a buffer with specified length from the pool. +func (NopBufferPool) Get(length int) *[]byte { + b := make([]byte, length) + return &b +} + +// Put returns a buffer to the pool. +func (NopBufferPool) Put(*[]byte) { +} diff --git a/go-controller/vendor/google.golang.org/grpc/mem/buffer_slice.go b/go-controller/vendor/google.golang.org/grpc/mem/buffer_slice.go new file mode 100644 index 0000000000..228e9c2f20 --- /dev/null +++ b/go-controller/vendor/google.golang.org/grpc/mem/buffer_slice.go @@ -0,0 +1,226 @@ +/* + * + * Copyright 2024 gRPC authors. + * + * 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 mem + +import ( + "io" +) + +// BufferSlice offers a means to represent data that spans one or more Buffer +// instances. A BufferSlice is meant to be immutable after creation, and methods +// like Ref create and return copies of the slice. This is why all methods have +// value receivers rather than pointer receivers. +// +// Note that any of the methods that read the underlying buffers such as Ref, +// Len or CopyTo etc., will panic if any underlying buffers have already been +// freed. It is recommended to not directly interact with any of the underlying +// buffers directly, rather such interactions should be mediated through the +// various methods on this type. +// +// By convention, any APIs that return (mem.BufferSlice, error) should reduce +// the burden on the caller by never returning a mem.BufferSlice that needs to +// be freed if the error is non-nil, unless explicitly stated. +type BufferSlice []Buffer + +// Len returns the sum of the length of all the Buffers in this slice. +// +// # Warning +// +// Invoking the built-in len on a BufferSlice will return the number of buffers +// in the slice, and *not* the value returned by this function. +func (s BufferSlice) Len() int { + var length int + for _, b := range s { + length += b.Len() + } + return length +} + +// Ref invokes Ref on each buffer in the slice. +func (s BufferSlice) Ref() { + for _, b := range s { + b.Ref() + } +} + +// Free invokes Buffer.Free() on each Buffer in the slice. +func (s BufferSlice) Free() { + for _, b := range s { + b.Free() + } +} + +// CopyTo copies each of the underlying Buffer's data into the given buffer, +// returning the number of bytes copied. Has the same semantics as the copy +// builtin in that it will copy as many bytes as it can, stopping when either dst +// is full or s runs out of data, returning the minimum of s.Len() and len(dst). +func (s BufferSlice) CopyTo(dst []byte) int { + off := 0 + for _, b := range s { + off += copy(dst[off:], b.ReadOnlyData()) + } + return off +} + +// Materialize concatenates all the underlying Buffer's data into a single +// contiguous buffer using CopyTo. +func (s BufferSlice) Materialize() []byte { + l := s.Len() + if l == 0 { + return nil + } + out := make([]byte, l) + s.CopyTo(out) + return out +} + +// MaterializeToBuffer functions like Materialize except that it writes the data +// to a single Buffer pulled from the given BufferPool. +// +// As a special case, if the input BufferSlice only actually has one Buffer, this +// function simply increases the refcount before returning said Buffer. Freeing this +// buffer won't release it until the BufferSlice is itself released. +func (s BufferSlice) MaterializeToBuffer(pool BufferPool) Buffer { + if len(s) == 1 { + s[0].Ref() + return s[0] + } + sLen := s.Len() + if sLen == 0 { + return emptyBuffer{} + } + buf := pool.Get(sLen) + s.CopyTo(*buf) + return NewBuffer(buf, pool) +} + +// Reader returns a new Reader for the input slice after taking references to +// each underlying buffer. +func (s BufferSlice) Reader() Reader { + s.Ref() + return &sliceReader{ + data: s, + len: s.Len(), + } +} + +// Reader exposes a BufferSlice's data as an io.Reader, allowing it to interface +// with other parts systems. It also provides an additional convenience method +// Remaining(), which returns the number of unread bytes remaining in the slice. +// Buffers will be freed as they are read. +type Reader interface { + io.Reader + io.ByteReader + // Close frees the underlying BufferSlice and never returns an error. Subsequent + // calls to Read will return (0, io.EOF). + Close() error + // Remaining returns the number of unread bytes remaining in the slice. + Remaining() int +} + +type sliceReader struct { + data BufferSlice + len int + // The index into data[0].ReadOnlyData(). + bufferIdx int +} + +func (r *sliceReader) Remaining() int { + return r.len +} + +func (r *sliceReader) Close() error { + r.data.Free() + r.data = nil + r.len = 0 + return nil +} + +func (r *sliceReader) freeFirstBufferIfEmpty() bool { + if len(r.data) == 0 || r.bufferIdx != len(r.data[0].ReadOnlyData()) { + return false + } + + r.data[0].Free() + r.data = r.data[1:] + r.bufferIdx = 0 + return true +} + +func (r *sliceReader) Read(buf []byte) (n int, _ error) { + if r.len == 0 { + return 0, io.EOF + } + + for len(buf) != 0 && r.len != 0 { + // Copy as much as possible from the first Buffer in the slice into the + // given byte slice. + data := r.data[0].ReadOnlyData() + copied := copy(buf, data[r.bufferIdx:]) + r.len -= copied // Reduce len by the number of bytes copied. + r.bufferIdx += copied // Increment the buffer index. + n += copied // Increment the total number of bytes read. + buf = buf[copied:] // Shrink the given byte slice. + + // If we have copied all the data from the first Buffer, free it and advance to + // the next in the slice. + r.freeFirstBufferIfEmpty() + } + + return n, nil +} + +func (r *sliceReader) ReadByte() (byte, error) { + if r.len == 0 { + return 0, io.EOF + } + + // There may be any number of empty buffers in the slice, clear them all until a + // non-empty buffer is reached. This is guaranteed to exit since r.len is not 0. + for r.freeFirstBufferIfEmpty() { + } + + b := r.data[0].ReadOnlyData()[r.bufferIdx] + r.len-- + r.bufferIdx++ + // Free the first buffer in the slice if the last byte was read + r.freeFirstBufferIfEmpty() + return b, nil +} + +var _ io.Writer = (*writer)(nil) + +type writer struct { + buffers *BufferSlice + pool BufferPool +} + +func (w *writer) Write(p []byte) (n int, err error) { + b := Copy(p, w.pool) + *w.buffers = append(*w.buffers, b) + return b.Len(), nil +} + +// NewWriter wraps the given BufferSlice and BufferPool to implement the +// io.Writer interface. Every call to Write copies the contents of the given +// buffer into a new Buffer pulled from the given pool and the Buffer is added to +// the given BufferSlice. +func NewWriter(buffers *BufferSlice, pool BufferPool) io.Writer { + return &writer{buffers: buffers, pool: pool} +} diff --git a/go-controller/vendor/google.golang.org/grpc/mem/buffers.go b/go-controller/vendor/google.golang.org/grpc/mem/buffers.go new file mode 100644 index 0000000000..ecbf0b9a73 --- /dev/null +++ b/go-controller/vendor/google.golang.org/grpc/mem/buffers.go @@ -0,0 +1,268 @@ +/* + * + * Copyright 2024 gRPC authors. + * + * 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 mem provides utilities that facilitate memory reuse in byte slices +// that are used as buffers. +// +// # Experimental +// +// Notice: All APIs in this package are EXPERIMENTAL and may be changed or +// removed in a later release. +package mem + +import ( + "fmt" + "sync" + "sync/atomic" +) + +// A Buffer represents a reference counted piece of data (in bytes) that can be +// acquired by a call to NewBuffer() or Copy(). A reference to a Buffer may be +// released by calling Free(), which invokes the free function given at creation +// only after all references are released. +// +// Note that a Buffer is not safe for concurrent access and instead each +// goroutine should use its own reference to the data, which can be acquired via +// a call to Ref(). +// +// Attempts to access the underlying data after releasing the reference to the +// Buffer will panic. +type Buffer interface { + // ReadOnlyData returns the underlying byte slice. Note that it is undefined + // behavior to modify the contents of this slice in any way. + ReadOnlyData() []byte + // Ref increases the reference counter for this Buffer. + Ref() + // Free decrements this Buffer's reference counter and frees the underlying + // byte slice if the counter reaches 0 as a result of this call. + Free() + // Len returns the Buffer's size. + Len() int + + split(n int) (left, right Buffer) + read(buf []byte) (int, Buffer) +} + +var ( + bufferPoolingThreshold = 1 << 10 + + bufferObjectPool = sync.Pool{New: func() any { return new(buffer) }} + refObjectPool = sync.Pool{New: func() any { return new(atomic.Int32) }} +) + +// IsBelowBufferPoolingThreshold returns true if the given size is less than or +// equal to the threshold for buffer pooling. This is used to determine whether +// to pool buffers or allocate them directly. +func IsBelowBufferPoolingThreshold(size int) bool { + return size <= bufferPoolingThreshold +} + +type buffer struct { + origData *[]byte + data []byte + refs *atomic.Int32 + pool BufferPool +} + +func newBuffer() *buffer { + return bufferObjectPool.Get().(*buffer) +} + +// NewBuffer creates a new Buffer from the given data, initializing the reference +// counter to 1. The data will then be returned to the given pool when all +// references to the returned Buffer are released. As a special case to avoid +// additional allocations, if the given buffer pool is nil, the returned buffer +// will be a "no-op" Buffer where invoking Buffer.Free() does nothing and the +// underlying data is never freed. +// +// Note that the backing array of the given data is not copied. +func NewBuffer(data *[]byte, pool BufferPool) Buffer { + // Use the buffer's capacity instead of the length, otherwise buffers may + // not be reused under certain conditions. For example, if a large buffer + // is acquired from the pool, but fewer bytes than the buffering threshold + // are written to it, the buffer will not be returned to the pool. + if pool == nil || IsBelowBufferPoolingThreshold(cap(*data)) { + return (SliceBuffer)(*data) + } + b := newBuffer() + b.origData = data + b.data = *data + b.pool = pool + b.refs = refObjectPool.Get().(*atomic.Int32) + b.refs.Add(1) + return b +} + +// Copy creates a new Buffer from the given data, initializing the reference +// counter to 1. +// +// It acquires a []byte from the given pool and copies over the backing array +// of the given data. The []byte acquired from the pool is returned to the +// pool when all references to the returned Buffer are released. +func Copy(data []byte, pool BufferPool) Buffer { + if IsBelowBufferPoolingThreshold(len(data)) { + buf := make(SliceBuffer, len(data)) + copy(buf, data) + return buf + } + + buf := pool.Get(len(data)) + copy(*buf, data) + return NewBuffer(buf, pool) +} + +func (b *buffer) ReadOnlyData() []byte { + if b.refs == nil { + panic("Cannot read freed buffer") + } + return b.data +} + +func (b *buffer) Ref() { + if b.refs == nil { + panic("Cannot ref freed buffer") + } + b.refs.Add(1) +} + +func (b *buffer) Free() { + if b.refs == nil { + panic("Cannot free freed buffer") + } + + refs := b.refs.Add(-1) + switch { + case refs > 0: + return + case refs == 0: + if b.pool != nil { + b.pool.Put(b.origData) + } + + refObjectPool.Put(b.refs) + b.origData = nil + b.data = nil + b.refs = nil + b.pool = nil + bufferObjectPool.Put(b) + default: + panic("Cannot free freed buffer") + } +} + +func (b *buffer) Len() int { + return len(b.ReadOnlyData()) +} + +func (b *buffer) split(n int) (Buffer, Buffer) { + if b.refs == nil { + panic("Cannot split freed buffer") + } + + b.refs.Add(1) + split := newBuffer() + split.origData = b.origData + split.data = b.data[n:] + split.refs = b.refs + split.pool = b.pool + + b.data = b.data[:n] + + return b, split +} + +func (b *buffer) read(buf []byte) (int, Buffer) { + if b.refs == nil { + panic("Cannot read freed buffer") + } + + n := copy(buf, b.data) + if n == len(b.data) { + b.Free() + return n, nil + } + + b.data = b.data[n:] + return n, b +} + +func (b *buffer) String() string { + return fmt.Sprintf("mem.Buffer(%p, data: %p, length: %d)", b, b.ReadOnlyData(), len(b.ReadOnlyData())) +} + +// ReadUnsafe reads bytes from the given Buffer into the provided slice. +// It does not perform safety checks. +func ReadUnsafe(dst []byte, buf Buffer) (int, Buffer) { + return buf.read(dst) +} + +// SplitUnsafe modifies the receiver to point to the first n bytes while it +// returns a new reference to the remaining bytes. The returned Buffer +// functions just like a normal reference acquired using Ref(). +func SplitUnsafe(buf Buffer, n int) (left, right Buffer) { + return buf.split(n) +} + +type emptyBuffer struct{} + +func (e emptyBuffer) ReadOnlyData() []byte { + return nil +} + +func (e emptyBuffer) Ref() {} +func (e emptyBuffer) Free() {} + +func (e emptyBuffer) Len() int { + return 0 +} + +func (e emptyBuffer) split(int) (left, right Buffer) { + return e, e +} + +func (e emptyBuffer) read([]byte) (int, Buffer) { + return 0, e +} + +// SliceBuffer is a Buffer implementation that wraps a byte slice. It provides +// methods for reading, splitting, and managing the byte slice. +type SliceBuffer []byte + +// ReadOnlyData returns the byte slice. +func (s SliceBuffer) ReadOnlyData() []byte { return s } + +// Ref is a noop implementation of Ref. +func (s SliceBuffer) Ref() {} + +// Free is a noop implementation of Free. +func (s SliceBuffer) Free() {} + +// Len is a noop implementation of Len. +func (s SliceBuffer) Len() int { return len(s) } + +func (s SliceBuffer) split(n int) (left, right Buffer) { + return s[:n], s[n:] +} + +func (s SliceBuffer) read(buf []byte) (int, Buffer) { + n := copy(buf, s) + if n == len(s) { + return n, nil + } + return n, s[n:] +} diff --git a/go-controller/vendor/google.golang.org/grpc/metadata/metadata.go b/go-controller/vendor/google.golang.org/grpc/metadata/metadata.go index 1e9485fd6e..d2e15253bb 100644 --- a/go-controller/vendor/google.golang.org/grpc/metadata/metadata.go +++ b/go-controller/vendor/google.golang.org/grpc/metadata/metadata.go @@ -213,11 +213,6 @@ func FromIncomingContext(ctx context.Context) (MD, bool) { // ValueFromIncomingContext returns the metadata value corresponding to the metadata // key from the incoming metadata if it exists. Keys are matched in a case insensitive // manner. -// -// # Experimental -// -// Notice: This API is EXPERIMENTAL and may be changed or removed in a -// later release. func ValueFromIncomingContext(ctx context.Context, key string) []string { md, ok := ctx.Value(mdIncomingKey{}).(MD) if !ok { @@ -228,7 +223,7 @@ func ValueFromIncomingContext(ctx context.Context, key string) []string { return copyOf(v) } for k, v := range md { - // Case insenitive comparison: MD is a map, and there's no guarantee + // Case insensitive comparison: MD is a map, and there's no guarantee // that the MD attached to the context is created using our helper // functions. if strings.EqualFold(k, key) { diff --git a/go-controller/vendor/google.golang.org/grpc/preloader.go b/go-controller/vendor/google.golang.org/grpc/preloader.go index 73bd633643..e87a17f36a 100644 --- a/go-controller/vendor/google.golang.org/grpc/preloader.go +++ b/go-controller/vendor/google.golang.org/grpc/preloader.go @@ -20,6 +20,7 @@ package grpc import ( "google.golang.org/grpc/codes" + "google.golang.org/grpc/mem" "google.golang.org/grpc/status" ) @@ -31,9 +32,10 @@ import ( // later release. type PreparedMsg struct { // Struct for preparing msg before sending them - encodedData []byte + encodedData mem.BufferSlice hdr []byte - payload []byte + payload mem.BufferSlice + pf payloadFormat } // Encode marshalls and compresses the message using the codec and compressor for the stream. @@ -57,11 +59,27 @@ func (p *PreparedMsg) Encode(s Stream, msg any) error { if err != nil { return err } - p.encodedData = data - compData, err := compress(data, rpcInfo.preloaderInfo.cp, rpcInfo.preloaderInfo.comp) + + materializedData := data.Materialize() + data.Free() + p.encodedData = mem.BufferSlice{mem.NewBuffer(&materializedData, nil)} + + // TODO: it should be possible to grab the bufferPool from the underlying + // stream implementation with a type cast to its actual type (such as + // addrConnStream) and accessing the buffer pool directly. + var compData mem.BufferSlice + compData, p.pf, err = compress(p.encodedData, rpcInfo.preloaderInfo.cp, rpcInfo.preloaderInfo.comp, mem.DefaultBufferPool()) if err != nil { return err } - p.hdr, p.payload = msgHeader(data, compData) + + if p.pf.isCompressed() { + materializedCompData := compData.Materialize() + compData.Free() + compData = mem.BufferSlice{mem.NewBuffer(&materializedCompData, nil)} + } + + p.hdr, p.payload = msgHeader(p.encodedData, compData, p.pf) + return nil } diff --git a/go-controller/vendor/google.golang.org/grpc/regenerate.sh b/go-controller/vendor/google.golang.org/grpc/regenerate.sh deleted file mode 100644 index 3edca296c2..0000000000 --- a/go-controller/vendor/google.golang.org/grpc/regenerate.sh +++ /dev/null @@ -1,123 +0,0 @@ -#!/bin/bash -# Copyright 2020 gRPC authors. -# -# 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. - -set -eu -o pipefail - -WORKDIR=$(mktemp -d) - -function finish { - rm -rf "$WORKDIR" -} -trap finish EXIT - -export GOBIN=${WORKDIR}/bin -export PATH=${GOBIN}:${PATH} -mkdir -p ${GOBIN} - -echo "remove existing generated files" -# grpc_testing_not_regenerate/*.pb.go is not re-generated, -# see grpc_testing_not_regenerate/README.md for details. -rm -f $(find . -name '*.pb.go' | grep -v 'grpc_testing_not_regenerate') - -echo "go install google.golang.org/protobuf/cmd/protoc-gen-go" -(cd test/tools && go install google.golang.org/protobuf/cmd/protoc-gen-go) - -echo "go install cmd/protoc-gen-go-grpc" -(cd cmd/protoc-gen-go-grpc && go install .) - -echo "git clone https://github.com/grpc/grpc-proto" -git clone --quiet https://github.com/grpc/grpc-proto ${WORKDIR}/grpc-proto - -echo "git clone https://github.com/protocolbuffers/protobuf" -git clone --quiet https://github.com/protocolbuffers/protobuf ${WORKDIR}/protobuf - -# Pull in code.proto as a proto dependency -mkdir -p ${WORKDIR}/googleapis/google/rpc -echo "curl https://raw.githubusercontent.com/googleapis/googleapis/master/google/rpc/code.proto" -curl --silent https://raw.githubusercontent.com/googleapis/googleapis/master/google/rpc/code.proto > ${WORKDIR}/googleapis/google/rpc/code.proto - -mkdir -p ${WORKDIR}/out - -# Generates sources without the embed requirement -LEGACY_SOURCES=( - ${WORKDIR}/grpc-proto/grpc/binlog/v1/binarylog.proto - ${WORKDIR}/grpc-proto/grpc/channelz/v1/channelz.proto - ${WORKDIR}/grpc-proto/grpc/health/v1/health.proto - ${WORKDIR}/grpc-proto/grpc/lb/v1/load_balancer.proto - profiling/proto/service.proto - ${WORKDIR}/grpc-proto/grpc/reflection/v1alpha/reflection.proto - ${WORKDIR}/grpc-proto/grpc/reflection/v1/reflection.proto -) - -# Generates only the new gRPC Service symbols -SOURCES=( - $(git ls-files --exclude-standard --cached --others "*.proto" | grep -v '^profiling/proto/service.proto$') - ${WORKDIR}/grpc-proto/grpc/gcp/altscontext.proto - ${WORKDIR}/grpc-proto/grpc/gcp/handshaker.proto - ${WORKDIR}/grpc-proto/grpc/gcp/transport_security_common.proto - ${WORKDIR}/grpc-proto/grpc/lookup/v1/rls.proto - ${WORKDIR}/grpc-proto/grpc/lookup/v1/rls_config.proto - ${WORKDIR}/grpc-proto/grpc/testing/*.proto - ${WORKDIR}/grpc-proto/grpc/core/*.proto -) - -# These options of the form 'Mfoo.proto=bar' instruct the codegen to use an -# import path of 'bar' in the generated code when 'foo.proto' is imported in -# one of the sources. -# -# Note that the protos listed here are all for testing purposes. All protos to -# be used externally should have a go_package option (and they don't need to be -# listed here). -OPTS=Mgrpc/core/stats.proto=google.golang.org/grpc/interop/grpc_testing/core,\ -Mgrpc/testing/benchmark_service.proto=google.golang.org/grpc/interop/grpc_testing,\ -Mgrpc/testing/stats.proto=google.golang.org/grpc/interop/grpc_testing,\ -Mgrpc/testing/report_qps_scenario_service.proto=google.golang.org/grpc/interop/grpc_testing,\ -Mgrpc/testing/messages.proto=google.golang.org/grpc/interop/grpc_testing,\ -Mgrpc/testing/worker_service.proto=google.golang.org/grpc/interop/grpc_testing,\ -Mgrpc/testing/control.proto=google.golang.org/grpc/interop/grpc_testing,\ -Mgrpc/testing/test.proto=google.golang.org/grpc/interop/grpc_testing,\ -Mgrpc/testing/payloads.proto=google.golang.org/grpc/interop/grpc_testing,\ -Mgrpc/testing/empty.proto=google.golang.org/grpc/interop/grpc_testing - -for src in ${SOURCES[@]}; do - echo "protoc ${src}" - protoc --go_out=${OPTS}:${WORKDIR}/out --go-grpc_out=${OPTS},use_generic_streams_experimental=true:${WORKDIR}/out \ - -I"." \ - -I${WORKDIR}/grpc-proto \ - -I${WORKDIR}/googleapis \ - -I${WORKDIR}/protobuf/src \ - ${src} -done - -for src in ${LEGACY_SOURCES[@]}; do - echo "protoc ${src}" - protoc --go_out=${OPTS}:${WORKDIR}/out --go-grpc_out=${OPTS},require_unimplemented_servers=false:${WORKDIR}/out \ - -I"." \ - -I${WORKDIR}/grpc-proto \ - -I${WORKDIR}/googleapis \ - -I${WORKDIR}/protobuf/src \ - ${src} -done - -# The go_package option in grpc/lookup/v1/rls.proto doesn't match the -# current location. Move it into the right place. -mkdir -p ${WORKDIR}/out/google.golang.org/grpc/internal/proto/grpc_lookup_v1 -mv ${WORKDIR}/out/google.golang.org/grpc/lookup/grpc_lookup_v1/* ${WORKDIR}/out/google.golang.org/grpc/internal/proto/grpc_lookup_v1 - -# grpc_testing_not_regenerate/*.pb.go are not re-generated, -# see grpc_testing_not_regenerate/README.md for details. -rm ${WORKDIR}/out/google.golang.org/grpc/reflection/test/grpc_testing_not_regenerate/*.pb.go - -cp -R ${WORKDIR}/out/google.golang.org/grpc/* . diff --git a/go-controller/vendor/google.golang.org/grpc/resolver_wrapper.go b/go-controller/vendor/google.golang.org/grpc/resolver_wrapper.go index c5fb45236f..23bb3fb258 100644 --- a/go-controller/vendor/google.golang.org/grpc/resolver_wrapper.go +++ b/go-controller/vendor/google.golang.org/grpc/resolver_wrapper.go @@ -66,7 +66,7 @@ func newCCResolverWrapper(cc *ClientConn) *ccResolverWrapper { // any newly created ccResolverWrapper, except that close may be called instead. func (ccr *ccResolverWrapper) start() error { errCh := make(chan error) - ccr.serializer.Schedule(func(ctx context.Context) { + ccr.serializer.TrySchedule(func(ctx context.Context) { if ctx.Err() != nil { return } @@ -85,7 +85,7 @@ func (ccr *ccResolverWrapper) start() error { } func (ccr *ccResolverWrapper) resolveNow(o resolver.ResolveNowOptions) { - ccr.serializer.Schedule(func(ctx context.Context) { + ccr.serializer.TrySchedule(func(ctx context.Context) { if ctx.Err() != nil || ccr.resolver == nil { return } @@ -102,7 +102,7 @@ func (ccr *ccResolverWrapper) close() { ccr.closed = true ccr.mu.Unlock() - ccr.serializer.Schedule(func(context.Context) { + ccr.serializer.TrySchedule(func(context.Context) { if ccr.resolver == nil { return } @@ -177,6 +177,9 @@ func (ccr *ccResolverWrapper) ParseServiceConfig(scJSON string) *serviceconfig.P // addChannelzTraceEvent adds a channelz trace event containing the new // state received from resolver implementations. func (ccr *ccResolverWrapper) addChannelzTraceEvent(s resolver.State) { + if !logger.V(0) && !channelz.IsOn() { + return + } var updates []string var oldSC, newSC *ServiceConfig var oldOK, newOK bool diff --git a/go-controller/vendor/google.golang.org/grpc/rpc_util.go b/go-controller/vendor/google.golang.org/grpc/rpc_util.go index fdd49e6e91..aba1ae3e67 100644 --- a/go-controller/vendor/google.golang.org/grpc/rpc_util.go +++ b/go-controller/vendor/google.golang.org/grpc/rpc_util.go @@ -19,7 +19,6 @@ package grpc import ( - "bytes" "compress/gzip" "context" "encoding/binary" @@ -35,6 +34,7 @@ import ( "google.golang.org/grpc/encoding" "google.golang.org/grpc/encoding/proto" "google.golang.org/grpc/internal/transport" + "google.golang.org/grpc/mem" "google.golang.org/grpc/metadata" "google.golang.org/grpc/peer" "google.golang.org/grpc/stats" @@ -220,8 +220,8 @@ type HeaderCallOption struct { HeaderAddr *metadata.MD } -func (o HeaderCallOption) before(c *callInfo) error { return nil } -func (o HeaderCallOption) after(c *callInfo, attempt *csAttempt) { +func (o HeaderCallOption) before(*callInfo) error { return nil } +func (o HeaderCallOption) after(_ *callInfo, attempt *csAttempt) { *o.HeaderAddr, _ = attempt.s.Header() } @@ -242,8 +242,8 @@ type TrailerCallOption struct { TrailerAddr *metadata.MD } -func (o TrailerCallOption) before(c *callInfo) error { return nil } -func (o TrailerCallOption) after(c *callInfo, attempt *csAttempt) { +func (o TrailerCallOption) before(*callInfo) error { return nil } +func (o TrailerCallOption) after(_ *callInfo, attempt *csAttempt) { *o.TrailerAddr = attempt.s.Trailer() } @@ -264,24 +264,20 @@ type PeerCallOption struct { PeerAddr *peer.Peer } -func (o PeerCallOption) before(c *callInfo) error { return nil } -func (o PeerCallOption) after(c *callInfo, attempt *csAttempt) { +func (o PeerCallOption) before(*callInfo) error { return nil } +func (o PeerCallOption) after(_ *callInfo, attempt *csAttempt) { if x, ok := peer.FromContext(attempt.s.Context()); ok { *o.PeerAddr = *x } } -// WaitForReady configures the action to take when an RPC is attempted on broken -// connections or unreachable servers. If waitForReady is false and the -// connection is in the TRANSIENT_FAILURE state, the RPC will fail -// immediately. Otherwise, the RPC client will block the call until a -// connection is available (or the call is canceled or times out) and will -// retry the call if it fails due to a transient error. gRPC will not retry if -// data was written to the wire unless the server indicates it did not process -// the data. Please refer to -// https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md. +// WaitForReady configures the RPC's behavior when the client is in +// TRANSIENT_FAILURE, which occurs when all addresses fail to connect. If +// waitForReady is false, the RPC will fail immediately. Otherwise, the client +// will wait until a connection becomes available or the RPC's deadline is +// reached. // -// By default, RPCs don't "wait for ready". +// By default, RPCs do not "wait for ready". func WaitForReady(waitForReady bool) CallOption { return FailFastCallOption{FailFast: !waitForReady} } @@ -308,7 +304,7 @@ func (o FailFastCallOption) before(c *callInfo) error { c.failFast = o.FailFast return nil } -func (o FailFastCallOption) after(c *callInfo, attempt *csAttempt) {} +func (o FailFastCallOption) after(*callInfo, *csAttempt) {} // OnFinish returns a CallOption that configures a callback to be called when // the call completes. The error passed to the callback is the status of the @@ -343,7 +339,7 @@ func (o OnFinishCallOption) before(c *callInfo) error { return nil } -func (o OnFinishCallOption) after(c *callInfo, attempt *csAttempt) {} +func (o OnFinishCallOption) after(*callInfo, *csAttempt) {} // MaxCallRecvMsgSize returns a CallOption which sets the maximum message size // in bytes the client can receive. If this is not set, gRPC uses the default @@ -367,7 +363,7 @@ func (o MaxRecvMsgSizeCallOption) before(c *callInfo) error { c.maxReceiveMessageSize = &o.MaxRecvMsgSize return nil } -func (o MaxRecvMsgSizeCallOption) after(c *callInfo, attempt *csAttempt) {} +func (o MaxRecvMsgSizeCallOption) after(*callInfo, *csAttempt) {} // MaxCallSendMsgSize returns a CallOption which sets the maximum message size // in bytes the client can send. If this is not set, gRPC uses the default @@ -391,7 +387,7 @@ func (o MaxSendMsgSizeCallOption) before(c *callInfo) error { c.maxSendMessageSize = &o.MaxSendMsgSize return nil } -func (o MaxSendMsgSizeCallOption) after(c *callInfo, attempt *csAttempt) {} +func (o MaxSendMsgSizeCallOption) after(*callInfo, *csAttempt) {} // PerRPCCredentials returns a CallOption that sets credentials.PerRPCCredentials // for a call. @@ -414,7 +410,7 @@ func (o PerRPCCredsCallOption) before(c *callInfo) error { c.creds = o.Creds return nil } -func (o PerRPCCredsCallOption) after(c *callInfo, attempt *csAttempt) {} +func (o PerRPCCredsCallOption) after(*callInfo, *csAttempt) {} // UseCompressor returns a CallOption which sets the compressor used when // sending the request. If WithCompressor is also set, UseCompressor has @@ -442,7 +438,7 @@ func (o CompressorCallOption) before(c *callInfo) error { c.compressorType = o.CompressorType return nil } -func (o CompressorCallOption) after(c *callInfo, attempt *csAttempt) {} +func (o CompressorCallOption) after(*callInfo, *csAttempt) {} // CallContentSubtype returns a CallOption that will set the content-subtype // for a call. For example, if content-subtype is "json", the Content-Type over @@ -479,7 +475,7 @@ func (o ContentSubtypeCallOption) before(c *callInfo) error { c.contentSubtype = o.ContentSubtype return nil } -func (o ContentSubtypeCallOption) after(c *callInfo, attempt *csAttempt) {} +func (o ContentSubtypeCallOption) after(*callInfo, *csAttempt) {} // ForceCodec returns a CallOption that will set codec to be used for all // request and response messages for a call. The result of calling Name() will @@ -515,10 +511,50 @@ type ForceCodecCallOption struct { } func (o ForceCodecCallOption) before(c *callInfo) error { - c.codec = o.Codec + c.codec = newCodecV1Bridge(o.Codec) return nil } -func (o ForceCodecCallOption) after(c *callInfo, attempt *csAttempt) {} +func (o ForceCodecCallOption) after(*callInfo, *csAttempt) {} + +// ForceCodecV2 returns a CallOption that will set codec to be used for all +// request and response messages for a call. The result of calling Name() will +// be used as the content-subtype after converting to lowercase, unless +// CallContentSubtype is also used. +// +// See Content-Type on +// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests for +// more details. Also see the documentation on RegisterCodec and +// CallContentSubtype for more details on the interaction between Codec and +// content-subtype. +// +// This function is provided for advanced users; prefer to use only +// CallContentSubtype to select a registered codec instead. +// +// # Experimental +// +// Notice: This API is EXPERIMENTAL and may be changed or removed in a +// later release. +func ForceCodecV2(codec encoding.CodecV2) CallOption { + return ForceCodecV2CallOption{CodecV2: codec} +} + +// ForceCodecV2CallOption is a CallOption that indicates the codec used for +// marshaling messages. +// +// # Experimental +// +// Notice: This type is EXPERIMENTAL and may be changed or removed in a +// later release. +type ForceCodecV2CallOption struct { + CodecV2 encoding.CodecV2 +} + +func (o ForceCodecV2CallOption) before(c *callInfo) error { + c.codec = o.CodecV2 + return nil +} + +func (o ForceCodecV2CallOption) after(*callInfo, *csAttempt) {} // CallCustomCodec behaves like ForceCodec, but accepts a grpc.Codec instead of // an encoding.Codec. @@ -540,10 +576,10 @@ type CustomCodecCallOption struct { } func (o CustomCodecCallOption) before(c *callInfo) error { - c.codec = o.Codec + c.codec = newCodecV0Bridge(o.Codec) return nil } -func (o CustomCodecCallOption) after(c *callInfo, attempt *csAttempt) {} +func (o CustomCodecCallOption) after(*callInfo, *csAttempt) {} // MaxRetryRPCBufferSize returns a CallOption that limits the amount of memory // used for buffering this RPC's requests for retry purposes. @@ -571,7 +607,7 @@ func (o MaxRetryRPCBufferSizeCallOption) before(c *callInfo) error { c.maxRetryRPCBufferSize = o.MaxRetryRPCBufferSize return nil } -func (o MaxRetryRPCBufferSizeCallOption) after(c *callInfo, attempt *csAttempt) {} +func (o MaxRetryRPCBufferSizeCallOption) after(*callInfo, *csAttempt) {} // The format of the payload: compressed or not? type payloadFormat uint8 @@ -581,19 +617,28 @@ const ( compressionMade payloadFormat = 1 // compressed ) +func (pf payloadFormat) isCompressed() bool { + return pf == compressionMade +} + +type streamReader interface { + ReadHeader(header []byte) error + Read(n int) (mem.BufferSlice, error) +} + // parser reads complete gRPC messages from the underlying reader. type parser struct { // r is the underlying reader. // See the comment on recvMsg for the permissible // error types. - r io.Reader + r streamReader // The header of a gRPC message. Find more detail at // https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md header [5]byte - // recvBufferPool is the pool of shared receive buffers. - recvBufferPool SharedBufferPool + // bufferPool is the pool of shared receive buffers. + bufferPool mem.BufferPool } // recvMsg reads a complete gRPC message from the stream. @@ -608,14 +653,15 @@ type parser struct { // - an error from the status package // // No other error values or types must be returned, which also means -// that the underlying io.Reader must not return an incompatible +// that the underlying streamReader must not return an incompatible // error. -func (p *parser) recvMsg(maxReceiveMessageSize int) (pf payloadFormat, msg []byte, err error) { - if _, err := p.r.Read(p.header[:]); err != nil { +func (p *parser) recvMsg(maxReceiveMessageSize int) (payloadFormat, mem.BufferSlice, error) { + err := p.r.ReadHeader(p.header[:]) + if err != nil { return 0, nil, err } - pf = payloadFormat(p.header[0]) + pf := payloadFormat(p.header[0]) length := binary.BigEndian.Uint32(p.header[1:]) if length == 0 { @@ -627,20 +673,21 @@ func (p *parser) recvMsg(maxReceiveMessageSize int) (pf payloadFormat, msg []byt if int(length) > maxReceiveMessageSize { return 0, nil, status.Errorf(codes.ResourceExhausted, "grpc: received message larger than max (%d vs. %d)", length, maxReceiveMessageSize) } - msg = p.recvBufferPool.Get(int(length)) - if _, err := p.r.Read(msg); err != nil { + + data, err := p.r.Read(int(length)) + if err != nil { if err == io.EOF { err = io.ErrUnexpectedEOF } return 0, nil, err } - return pf, msg, nil + return pf, data, nil } // encode serializes msg and returns a buffer containing the message, or an // error if it is too large to be transmitted by grpc. If msg is nil, it // generates an empty message. -func encode(c baseCodec, msg any) ([]byte, error) { +func encode(c baseCodec, msg any) (mem.BufferSlice, error) { if msg == nil { // NOTE: typed nils will not be caught by this check return nil, nil } @@ -648,7 +695,8 @@ func encode(c baseCodec, msg any) ([]byte, error) { if err != nil { return nil, status.Errorf(codes.Internal, "grpc: error while marshaling: %v", err.Error()) } - if uint(len(b)) > math.MaxUint32 { + if uint(b.Len()) > math.MaxUint32 { + b.Free() return nil, status.Errorf(codes.ResourceExhausted, "grpc: message too large (%d bytes)", len(b)) } return b, nil @@ -659,34 +707,41 @@ func encode(c baseCodec, msg any) ([]byte, error) { // indicating no compression was done. // // TODO(dfawley): eliminate cp parameter by wrapping Compressor in an encoding.Compressor. -func compress(in []byte, cp Compressor, compressor encoding.Compressor) ([]byte, error) { - if compressor == nil && cp == nil { - return nil, nil - } - if len(in) == 0 { - return nil, nil +func compress(in mem.BufferSlice, cp Compressor, compressor encoding.Compressor, pool mem.BufferPool) (mem.BufferSlice, payloadFormat, error) { + if (compressor == nil && cp == nil) || in.Len() == 0 { + return nil, compressionNone, nil } + var out mem.BufferSlice + w := mem.NewWriter(&out, pool) wrapErr := func(err error) error { + out.Free() return status.Errorf(codes.Internal, "grpc: error while compressing: %v", err.Error()) } - cbuf := &bytes.Buffer{} if compressor != nil { - z, err := compressor.Compress(cbuf) + z, err := compressor.Compress(w) if err != nil { - return nil, wrapErr(err) + return nil, 0, wrapErr(err) } - if _, err := z.Write(in); err != nil { - return nil, wrapErr(err) + for _, b := range in { + if _, err := z.Write(b.ReadOnlyData()); err != nil { + return nil, 0, wrapErr(err) + } } if err := z.Close(); err != nil { - return nil, wrapErr(err) + return nil, 0, wrapErr(err) } } else { - if err := cp.Do(cbuf, in); err != nil { - return nil, wrapErr(err) + // This is obviously really inefficient since it fully materializes the data, but + // there is no way around this with the old Compressor API. At least it attempts + // to return the buffer to the provider, in the hopes it can be reused (maybe + // even by a subsequent call to this very function). + buf := in.MaterializeToBuffer(pool) + defer buf.Free() + if err := cp.Do(w, buf.ReadOnlyData()); err != nil { + return nil, 0, wrapErr(err) } } - return cbuf.Bytes(), nil + return out, compressionMade, nil } const ( @@ -697,33 +752,36 @@ const ( // msgHeader returns a 5-byte header for the message being transmitted and the // payload, which is compData if non-nil or data otherwise. -func msgHeader(data, compData []byte) (hdr []byte, payload []byte) { +func msgHeader(data, compData mem.BufferSlice, pf payloadFormat) (hdr []byte, payload mem.BufferSlice) { hdr = make([]byte, headerLen) - if compData != nil { - hdr[0] = byte(compressionMade) - data = compData + hdr[0] = byte(pf) + + var length uint32 + if pf.isCompressed() { + length = uint32(compData.Len()) + payload = compData } else { - hdr[0] = byte(compressionNone) + length = uint32(data.Len()) + payload = data } // Write length of payload into buf - binary.BigEndian.PutUint32(hdr[payloadLen:], uint32(len(data))) - return hdr, data + binary.BigEndian.PutUint32(hdr[payloadLen:], length) + return hdr, payload } -func outPayload(client bool, msg any, data, payload []byte, t time.Time) *stats.OutPayload { +func outPayload(client bool, msg any, dataLength, payloadLength int, t time.Time) *stats.OutPayload { return &stats.OutPayload{ Client: client, Payload: msg, - Data: data, - Length: len(data), - WireLength: len(payload) + headerLen, - CompressedLength: len(payload), + Length: dataLength, + WireLength: payloadLength + headerLen, + CompressedLength: payloadLength, SentTime: t, } } -func checkRecvPayload(pf payloadFormat, recvCompress string, haveCompressor bool) *status.Status { +func checkRecvPayload(pf payloadFormat, recvCompress string, haveCompressor bool, isServer bool) *status.Status { switch pf { case compressionNone: case compressionMade: @@ -731,7 +789,10 @@ func checkRecvPayload(pf payloadFormat, recvCompress string, haveCompressor bool return status.New(codes.Internal, "grpc: compressed flag set with identity or empty encoding") } if !haveCompressor { - return status.Newf(codes.Unimplemented, "grpc: Decompressor is not installed for grpc-encoding %q", recvCompress) + if isServer { + return status.Newf(codes.Unimplemented, "grpc: Decompressor is not installed for grpc-encoding %q", recvCompress) + } + return status.Newf(codes.Internal, "grpc: Decompressor is not installed for grpc-encoding %q", recvCompress) } default: return status.Newf(codes.Internal, "grpc: received unexpected payload format %d", pf) @@ -741,104 +802,129 @@ func checkRecvPayload(pf payloadFormat, recvCompress string, haveCompressor bool type payloadInfo struct { compressedLength int // The compressed length got from wire. - uncompressedBytes []byte + uncompressedBytes mem.BufferSlice +} + +func (p *payloadInfo) free() { + if p != nil && p.uncompressedBytes != nil { + p.uncompressedBytes.Free() + } } // recvAndDecompress reads a message from the stream, decompressing it if necessary. // // Cancelling the returned cancel function releases the buffer back to the pool. So the caller should cancel as soon as // the buffer is no longer needed. -func recvAndDecompress(p *parser, s *transport.Stream, dc Decompressor, maxReceiveMessageSize int, payInfo *payloadInfo, compressor encoding.Compressor, -) (uncompressedBuf []byte, cancel func(), err error) { - pf, compressedBuf, err := p.recvMsg(maxReceiveMessageSize) +// TODO: Refactor this function to reduce the number of arguments. +// See: https://google.github.io/styleguide/go/best-practices.html#function-argument-lists +func recvAndDecompress(p *parser, s *transport.Stream, dc Decompressor, maxReceiveMessageSize int, payInfo *payloadInfo, compressor encoding.Compressor, isServer bool, +) (out mem.BufferSlice, err error) { + pf, compressed, err := p.recvMsg(maxReceiveMessageSize) if err != nil { - return nil, nil, err + return nil, err } - if st := checkRecvPayload(pf, s.RecvCompress(), compressor != nil || dc != nil); st != nil { - return nil, nil, st.Err() + compressedLength := compressed.Len() + + if st := checkRecvPayload(pf, s.RecvCompress(), compressor != nil || dc != nil, isServer); st != nil { + compressed.Free() + return nil, st.Err() } var size int - if pf == compressionMade { + if pf.isCompressed() { + defer compressed.Free() + // To match legacy behavior, if the decompressor is set by WithDecompressor or RPCDecompressor, // use this decompressor as the default. if dc != nil { - uncompressedBuf, err = dc.Do(bytes.NewReader(compressedBuf)) + var uncompressedBuf []byte + uncompressedBuf, err = dc.Do(compressed.Reader()) + if err == nil { + out = mem.BufferSlice{mem.NewBuffer(&uncompressedBuf, nil)} + } size = len(uncompressedBuf) } else { - uncompressedBuf, size, err = decompress(compressor, compressedBuf, maxReceiveMessageSize) + out, size, err = decompress(compressor, compressed, maxReceiveMessageSize, p.bufferPool) } if err != nil { - return nil, nil, status.Errorf(codes.Internal, "grpc: failed to decompress the received message: %v", err) + return nil, status.Errorf(codes.Internal, "grpc: failed to decompress the received message: %v", err) } if size > maxReceiveMessageSize { + out.Free() // TODO: Revisit the error code. Currently keep it consistent with java // implementation. - return nil, nil, status.Errorf(codes.ResourceExhausted, "grpc: received message after decompression larger than max (%d vs. %d)", size, maxReceiveMessageSize) + return nil, status.Errorf(codes.ResourceExhausted, "grpc: received message after decompression larger than max (%d vs. %d)", size, maxReceiveMessageSize) } } else { - uncompressedBuf = compressedBuf + out = compressed } if payInfo != nil { - payInfo.compressedLength = len(compressedBuf) - payInfo.uncompressedBytes = uncompressedBuf - - cancel = func() {} - } else { - cancel = func() { - p.recvBufferPool.Put(&compressedBuf) - } + payInfo.compressedLength = compressedLength + out.Ref() + payInfo.uncompressedBytes = out } - return uncompressedBuf, cancel, nil + return out, nil } // Using compressor, decompress d, returning data and size. // Optionally, if data will be over maxReceiveMessageSize, just return the size. -func decompress(compressor encoding.Compressor, d []byte, maxReceiveMessageSize int) ([]byte, int, error) { - dcReader, err := compressor.Decompress(bytes.NewReader(d)) +func decompress(compressor encoding.Compressor, d mem.BufferSlice, maxReceiveMessageSize int, pool mem.BufferPool) (mem.BufferSlice, int, error) { + dcReader, err := compressor.Decompress(d.Reader()) if err != nil { return nil, 0, err } - if sizer, ok := compressor.(interface { - DecompressedSize(compressedBytes []byte) int - }); ok { - if size := sizer.DecompressedSize(d); size >= 0 { - if size > maxReceiveMessageSize { - return nil, size, nil - } - // size is used as an estimate to size the buffer, but we - // will read more data if available. - // +MinRead so ReadFrom will not reallocate if size is correct. - // - // TODO: If we ensure that the buffer size is the same as the DecompressedSize, - // we can also utilize the recv buffer pool here. - buf := bytes.NewBuffer(make([]byte, 0, size+bytes.MinRead)) - bytesRead, err := buf.ReadFrom(io.LimitReader(dcReader, int64(maxReceiveMessageSize)+1)) - return buf.Bytes(), int(bytesRead), err - } + + // TODO: Can/should this still be preserved with the new BufferSlice API? Are + // there any actual benefits to allocating a single large buffer instead of + // multiple smaller ones? + //if sizer, ok := compressor.(interface { + // DecompressedSize(compressedBytes []byte) int + //}); ok { + // if size := sizer.DecompressedSize(d); size >= 0 { + // if size > maxReceiveMessageSize { + // return nil, size, nil + // } + // // size is used as an estimate to size the buffer, but we + // // will read more data if available. + // // +MinRead so ReadFrom will not reallocate if size is correct. + // // + // // TODO: If we ensure that the buffer size is the same as the DecompressedSize, + // // we can also utilize the recv buffer pool here. + // buf := bytes.NewBuffer(make([]byte, 0, size+bytes.MinRead)) + // bytesRead, err := buf.ReadFrom(io.LimitReader(dcReader, int64(maxReceiveMessageSize)+1)) + // return buf.Bytes(), int(bytesRead), err + // } + //} + + var out mem.BufferSlice + _, err = io.Copy(mem.NewWriter(&out, pool), io.LimitReader(dcReader, int64(maxReceiveMessageSize)+1)) + if err != nil { + out.Free() + return nil, 0, err } - // Read from LimitReader with limit max+1. So if the underlying - // reader is over limit, the result will be bigger than max. - d, err = io.ReadAll(io.LimitReader(dcReader, int64(maxReceiveMessageSize)+1)) - return d, len(d), err + return out, out.Len(), nil } // For the two compressor parameters, both should not be set, but if they are, // dc takes precedence over compressor. // TODO(dfawley): wrap the old compressor/decompressor using the new API? -func recv(p *parser, c baseCodec, s *transport.Stream, dc Decompressor, m any, maxReceiveMessageSize int, payInfo *payloadInfo, compressor encoding.Compressor) error { - buf, cancel, err := recvAndDecompress(p, s, dc, maxReceiveMessageSize, payInfo, compressor) +func recv(p *parser, c baseCodec, s *transport.Stream, dc Decompressor, m any, maxReceiveMessageSize int, payInfo *payloadInfo, compressor encoding.Compressor, isServer bool) error { + data, err := recvAndDecompress(p, s, dc, maxReceiveMessageSize, payInfo, compressor, isServer) if err != nil { return err } - defer cancel() - if err := c.Unmarshal(buf, m); err != nil { + // If the codec wants its own reference to the data, it can get it. Otherwise, always + // free the buffers. + defer data.Free() + + if err := c.Unmarshal(data, m); err != nil { return status.Errorf(codes.Internal, "grpc: failed to unmarshal the received message: %v", err) } + return nil } @@ -941,7 +1027,7 @@ func setCallInfoCodec(c *callInfo) error { // encoding.Codec (Name vs. String method name). We only support // setting content subtype from encoding.Codec to avoid a behavior // change with the deprecated version. - if ec, ok := c.codec.(encoding.Codec); ok { + if ec, ok := c.codec.(encoding.CodecV2); ok { c.contentSubtype = strings.ToLower(ec.Name()) } } @@ -950,12 +1036,12 @@ func setCallInfoCodec(c *callInfo) error { if c.contentSubtype == "" { // No codec specified in CallOptions; use proto by default. - c.codec = encoding.GetCodec(proto.Name) + c.codec = getCodec(proto.Name) return nil } // c.contentSubtype is already lowercased in CallContentSubtype - c.codec = encoding.GetCodec(c.contentSubtype) + c.codec = getCodec(c.contentSubtype) if c.codec == nil { return status.Errorf(codes.Internal, "no codec registered for content-subtype %s", c.contentSubtype) } diff --git a/go-controller/vendor/google.golang.org/grpc/server.go b/go-controller/vendor/google.golang.org/grpc/server.go index 89f8e4792b..d1e1415a40 100644 --- a/go-controller/vendor/google.golang.org/grpc/server.go +++ b/go-controller/vendor/google.golang.org/grpc/server.go @@ -45,6 +45,7 @@ import ( "google.golang.org/grpc/internal/grpcutil" "google.golang.org/grpc/internal/transport" "google.golang.org/grpc/keepalive" + "google.golang.org/grpc/mem" "google.golang.org/grpc/metadata" "google.golang.org/grpc/peer" "google.golang.org/grpc/stats" @@ -80,7 +81,7 @@ func init() { } internal.BinaryLogger = binaryLogger internal.JoinServerOptions = newJoinServerOption - internal.RecvBufferPool = recvBufferPool + internal.BufferPool = bufferPool } var statusOK = status.New(codes.OK, "") @@ -170,7 +171,7 @@ type serverOptions struct { maxHeaderListSize *uint32 headerTableSize *uint32 numServerWorkers uint32 - recvBufferPool SharedBufferPool + bufferPool mem.BufferPool waitForHandlers bool } @@ -181,7 +182,7 @@ var defaultServerOptions = serverOptions{ connectionTimeout: 120 * time.Second, writeBufferSize: defaultWriteBufSize, readBufferSize: defaultReadBufSize, - recvBufferPool: nopBufferPool{}, + bufferPool: mem.DefaultBufferPool(), } var globalServerOptions []ServerOption @@ -313,7 +314,7 @@ func KeepaliveEnforcementPolicy(kep keepalive.EnforcementPolicy) ServerOption { // Will be supported throughout 1.x. func CustomCodec(codec Codec) ServerOption { return newFuncServerOption(func(o *serverOptions) { - o.codec = codec + o.codec = newCodecV0Bridge(codec) }) } @@ -342,7 +343,22 @@ func CustomCodec(codec Codec) ServerOption { // later release. func ForceServerCodec(codec encoding.Codec) ServerOption { return newFuncServerOption(func(o *serverOptions) { - o.codec = codec + o.codec = newCodecV1Bridge(codec) + }) +} + +// ForceServerCodecV2 is the equivalent of ForceServerCodec, but for the new +// CodecV2 interface. +// +// Will be supported throughout 1.x. +// +// # Experimental +// +// Notice: This API is EXPERIMENTAL and may be changed or removed in a +// later release. +func ForceServerCodecV2(codecV2 encoding.CodecV2) ServerOption { + return newFuncServerOption(func(o *serverOptions) { + o.codec = codecV2 }) } @@ -592,26 +608,9 @@ func WaitForHandlers(w bool) ServerOption { }) } -// RecvBufferPool returns a ServerOption that configures the server -// to use the provided shared buffer pool for parsing incoming messages. Depending -// on the application's workload, this could result in reduced memory allocation. -// -// If you are unsure about how to implement a memory pool but want to utilize one, -// begin with grpc.NewSharedBufferPool. -// -// Note: The shared buffer pool feature will not be active if any of the following -// options are used: StatsHandler, EnableTracing, or binary logging. In such -// cases, the shared buffer pool will be ignored. -// -// Deprecated: use experimental.WithRecvBufferPool instead. Will be deleted in -// v1.60.0 or later. -func RecvBufferPool(bufferPool SharedBufferPool) ServerOption { - return recvBufferPool(bufferPool) -} - -func recvBufferPool(bufferPool SharedBufferPool) ServerOption { +func bufferPool(bufferPool mem.BufferPool) ServerOption { return newFuncServerOption(func(o *serverOptions) { - o.recvBufferPool = bufferPool + o.bufferPool = bufferPool }) } @@ -622,7 +621,7 @@ func recvBufferPool(bufferPool SharedBufferPool) ServerOption { // workload (assuming a QPS of a few thousand requests/sec). const serverWorkerResetThreshold = 1 << 16 -// serverWorkers blocks on a *transport.Stream channel forever and waits for +// serverWorker blocks on a *transport.Stream channel forever and waits for // data to be fed by serveStreams. This allows multiple requests to be // processed by the same goroutine, removing the need for expensive stack // re-allocations (see the runtime.morestack problem [1]). @@ -980,6 +979,7 @@ func (s *Server) newHTTP2Transport(c net.Conn) transport.ServerTransport { ChannelzParent: s.channelz, MaxHeaderListSize: s.opts.maxHeaderListSize, HeaderTableSize: s.opts.headerTableSize, + BufferPool: s.opts.bufferPool, } st, err := transport.NewServerTransport(c, config) if err != nil { @@ -1072,7 +1072,7 @@ var _ http.Handler = (*Server)(nil) // Notice: This API is EXPERIMENTAL and may be changed or removed in a // later release. func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { - st, err := transport.NewServerHandlerTransport(w, r, s.opts.statsHandlers) + st, err := transport.NewServerHandlerTransport(w, r, s.opts.statsHandlers, s.opts.bufferPool) if err != nil { // Errors returned from transport.NewServerHandlerTransport have // already been written to w. @@ -1142,20 +1142,35 @@ func (s *Server) sendResponse(ctx context.Context, t transport.ServerTransport, channelz.Error(logger, s.channelz, "grpc: server failed to encode response: ", err) return err } - compData, err := compress(data, cp, comp) + + compData, pf, err := compress(data, cp, comp, s.opts.bufferPool) if err != nil { + data.Free() channelz.Error(logger, s.channelz, "grpc: server failed to compress response: ", err) return err } - hdr, payload := msgHeader(data, compData) + + hdr, payload := msgHeader(data, compData, pf) + + defer func() { + compData.Free() + data.Free() + // payload does not need to be freed here, it is either data or compData, both of + // which are already freed. + }() + + dataLen := data.Len() + payloadLen := payload.Len() // TODO(dfawley): should we be checking len(data) instead? - if len(payload) > s.opts.maxSendMessageSize { - return status.Errorf(codes.ResourceExhausted, "grpc: trying to send message larger than max (%d vs. %d)", len(payload), s.opts.maxSendMessageSize) + if payloadLen > s.opts.maxSendMessageSize { + return status.Errorf(codes.ResourceExhausted, "grpc: trying to send message larger than max (%d vs. %d)", payloadLen, s.opts.maxSendMessageSize) } err = t.Write(stream, hdr, payload, opts) if err == nil { - for _, sh := range s.opts.statsHandlers { - sh.HandleRPC(ctx, outPayload(false, msg, data, payload, time.Now())) + if len(s.opts.statsHandlers) != 0 { + for _, sh := range s.opts.statsHandlers { + sh.HandleRPC(ctx, outPayload(false, msg, dataLen, payloadLen, time.Now())) + } } } return err @@ -1334,37 +1349,37 @@ func (s *Server) processUnaryRPC(ctx context.Context, t transport.ServerTranspor var payInfo *payloadInfo if len(shs) != 0 || len(binlogs) != 0 { payInfo = &payloadInfo{} + defer payInfo.free() } - d, cancel, err := recvAndDecompress(&parser{r: stream, recvBufferPool: s.opts.recvBufferPool}, stream, dc, s.opts.maxReceiveMessageSize, payInfo, decomp) + d, err := recvAndDecompress(&parser{r: stream, bufferPool: s.opts.bufferPool}, stream, dc, s.opts.maxReceiveMessageSize, payInfo, decomp, true) if err != nil { if e := t.WriteStatus(stream, status.Convert(err)); e != nil { channelz.Warningf(logger, s.channelz, "grpc: Server.processUnaryRPC failed to write status: %v", e) } return err } + defer d.Free() if channelz.IsOn() { t.IncrMsgRecv() } df := func(v any) error { - defer cancel() - if err := s.getCodec(stream.ContentSubtype()).Unmarshal(d, v); err != nil { return status.Errorf(codes.Internal, "grpc: error unmarshalling request: %v", err) } + for _, sh := range shs { sh.HandleRPC(ctx, &stats.InPayload{ RecvTime: time.Now(), Payload: v, - Length: len(d), + Length: d.Len(), WireLength: payInfo.compressedLength + headerLen, CompressedLength: payInfo.compressedLength, - Data: d, }) } if len(binlogs) != 0 { cm := &binarylog.ClientMessage{ - Message: d, + Message: d.Materialize(), } for _, binlog := range binlogs { binlog.Log(ctx, cm) @@ -1548,7 +1563,7 @@ func (s *Server) processStreamingRPC(ctx context.Context, t transport.ServerTran ctx: ctx, t: t, s: stream, - p: &parser{r: stream, recvBufferPool: s.opts.recvBufferPool}, + p: &parser{r: stream, bufferPool: s.opts.bufferPool}, codec: s.getCodec(stream.ContentSubtype()), maxReceiveMessageSize: s.opts.maxReceiveMessageSize, maxSendMessageSize: s.opts.maxSendMessageSize, @@ -1963,12 +1978,12 @@ func (s *Server) getCodec(contentSubtype string) baseCodec { return s.opts.codec } if contentSubtype == "" { - return encoding.GetCodec(proto.Name) + return getCodec(proto.Name) } - codec := encoding.GetCodec(contentSubtype) + codec := getCodec(contentSubtype) if codec == nil { logger.Warningf("Unsupported codec %q. Defaulting to %q for now. This will start to fail in future releases.", contentSubtype, proto.Name) - return encoding.GetCodec(proto.Name) + return getCodec(proto.Name) } return codec } diff --git a/go-controller/vendor/google.golang.org/grpc/shared_buffer_pool.go b/go-controller/vendor/google.golang.org/grpc/shared_buffer_pool.go deleted file mode 100644 index 48a64cfe8e..0000000000 --- a/go-controller/vendor/google.golang.org/grpc/shared_buffer_pool.go +++ /dev/null @@ -1,154 +0,0 @@ -/* - * - * Copyright 2023 gRPC authors. - * - * 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 grpc - -import "sync" - -// SharedBufferPool is a pool of buffers that can be shared, resulting in -// decreased memory allocation. Currently, in gRPC-go, it is only utilized -// for parsing incoming messages. -// -// # Experimental -// -// Notice: This API is EXPERIMENTAL and may be changed or removed in a -// later release. -type SharedBufferPool interface { - // Get returns a buffer with specified length from the pool. - // - // The returned byte slice may be not zero initialized. - Get(length int) []byte - - // Put returns a buffer to the pool. - Put(*[]byte) -} - -// NewSharedBufferPool creates a simple SharedBufferPool with buckets -// of different sizes to optimize memory usage. This prevents the pool from -// wasting large amounts of memory, even when handling messages of varying sizes. -// -// # Experimental -// -// Notice: This API is EXPERIMENTAL and may be changed or removed in a -// later release. -func NewSharedBufferPool() SharedBufferPool { - return &simpleSharedBufferPool{ - pools: [poolArraySize]simpleSharedBufferChildPool{ - newBytesPool(level0PoolMaxSize), - newBytesPool(level1PoolMaxSize), - newBytesPool(level2PoolMaxSize), - newBytesPool(level3PoolMaxSize), - newBytesPool(level4PoolMaxSize), - newBytesPool(0), - }, - } -} - -// simpleSharedBufferPool is a simple implementation of SharedBufferPool. -type simpleSharedBufferPool struct { - pools [poolArraySize]simpleSharedBufferChildPool -} - -func (p *simpleSharedBufferPool) Get(size int) []byte { - return p.pools[p.poolIdx(size)].Get(size) -} - -func (p *simpleSharedBufferPool) Put(bs *[]byte) { - p.pools[p.poolIdx(cap(*bs))].Put(bs) -} - -func (p *simpleSharedBufferPool) poolIdx(size int) int { - switch { - case size <= level0PoolMaxSize: - return level0PoolIdx - case size <= level1PoolMaxSize: - return level1PoolIdx - case size <= level2PoolMaxSize: - return level2PoolIdx - case size <= level3PoolMaxSize: - return level3PoolIdx - case size <= level4PoolMaxSize: - return level4PoolIdx - default: - return levelMaxPoolIdx - } -} - -const ( - level0PoolMaxSize = 16 // 16 B - level1PoolMaxSize = level0PoolMaxSize * 16 // 256 B - level2PoolMaxSize = level1PoolMaxSize * 16 // 4 KB - level3PoolMaxSize = level2PoolMaxSize * 16 // 64 KB - level4PoolMaxSize = level3PoolMaxSize * 16 // 1 MB -) - -const ( - level0PoolIdx = iota - level1PoolIdx - level2PoolIdx - level3PoolIdx - level4PoolIdx - levelMaxPoolIdx - poolArraySize -) - -type simpleSharedBufferChildPool interface { - Get(size int) []byte - Put(any) -} - -type bufferPool struct { - sync.Pool - - defaultSize int -} - -func (p *bufferPool) Get(size int) []byte { - bs := p.Pool.Get().(*[]byte) - - if cap(*bs) < size { - p.Pool.Put(bs) - - return make([]byte, size) - } - - return (*bs)[:size] -} - -func newBytesPool(size int) simpleSharedBufferChildPool { - return &bufferPool{ - Pool: sync.Pool{ - New: func() any { - bs := make([]byte, size) - return &bs - }, - }, - defaultSize: size, - } -} - -// nopBufferPool is a buffer pool just makes new buffer without pooling. -type nopBufferPool struct { -} - -func (nopBufferPool) Get(length int) []byte { - return make([]byte, length) -} - -func (nopBufferPool) Put(*[]byte) { -} diff --git a/go-controller/vendor/google.golang.org/grpc/stats/stats.go b/go-controller/vendor/google.golang.org/grpc/stats/stats.go index fdb0bd6518..71195c4943 100644 --- a/go-controller/vendor/google.golang.org/grpc/stats/stats.go +++ b/go-controller/vendor/google.golang.org/grpc/stats/stats.go @@ -77,9 +77,6 @@ type InPayload struct { // the call to HandleRPC which provides the InPayload returns and must be // copied if needed later. Payload any - // Data is the serialized message payload. - // Deprecated: Data will be removed in the next release. - Data []byte // Length is the size of the uncompressed payload data. Does not include any // framing (gRPC or HTTP/2). @@ -150,9 +147,6 @@ type OutPayload struct { // the call to HandleRPC which provides the OutPayload returns and must be // copied if needed later. Payload any - // Data is the serialized message payload. - // Deprecated: Data will be removed in the next release. - Data []byte // Length is the size of the uncompressed payload data. Does not include any // framing (gRPC or HTTP/2). Length int diff --git a/go-controller/vendor/google.golang.org/grpc/stream.go b/go-controller/vendor/google.golang.org/grpc/stream.go index 8051ef5b51..bb2b2a216c 100644 --- a/go-controller/vendor/google.golang.org/grpc/stream.go +++ b/go-controller/vendor/google.golang.org/grpc/stream.go @@ -41,6 +41,7 @@ import ( "google.golang.org/grpc/internal/serviceconfig" istatus "google.golang.org/grpc/internal/status" "google.golang.org/grpc/internal/transport" + "google.golang.org/grpc/mem" "google.golang.org/grpc/metadata" "google.golang.org/grpc/peer" "google.golang.org/grpc/stats" @@ -359,7 +360,7 @@ func newClientStreamWithParams(ctx context.Context, desc *StreamDesc, cc *Client cs.attempt = a return nil } - if err := cs.withRetry(op, func() { cs.bufferForRetryLocked(0, op) }); err != nil { + if err := cs.withRetry(op, func() { cs.bufferForRetryLocked(0, op, nil) }); err != nil { return nil, err } @@ -517,7 +518,7 @@ func (a *csAttempt) newStream() error { } a.s = s a.ctx = s.Context() - a.p = &parser{r: s, recvBufferPool: a.cs.cc.dopts.recvBufferPool} + a.p = &parser{r: s, bufferPool: a.cs.cc.dopts.copts.BufferPool} return nil } @@ -566,10 +567,15 @@ type clientStream struct { // place where we need to check if the attempt is nil. attempt *csAttempt // TODO(hedging): hedging will have multiple attempts simultaneously. - committed bool // active attempt committed for retry? - onCommit func() - buffer []func(a *csAttempt) error // operations to replay on retry - bufferSize int // current size of buffer + committed bool // active attempt committed for retry? + onCommit func() + replayBuffer []replayOp // operations to replay on retry + replayBufferSize int // current size of replayBuffer +} + +type replayOp struct { + op func(a *csAttempt) error + cleanup func() } // csAttempt implements a single transport stream attempt within a @@ -607,7 +613,12 @@ func (cs *clientStream) commitAttemptLocked() { cs.onCommit() } cs.committed = true - cs.buffer = nil + for _, op := range cs.replayBuffer { + if op.cleanup != nil { + op.cleanup() + } + } + cs.replayBuffer = nil } func (cs *clientStream) commitAttempt() { @@ -732,7 +743,7 @@ func (cs *clientStream) retryLocked(attempt *csAttempt, lastErr error) error { // the stream is canceled. return err } - // Note that the first op in the replay buffer always sets cs.attempt + // Note that the first op in replayBuffer always sets cs.attempt // if it is able to pick a transport and create a stream. if lastErr = cs.replayBufferLocked(attempt); lastErr == nil { return nil @@ -761,7 +772,7 @@ func (cs *clientStream) withRetry(op func(a *csAttempt) error, onSuccess func()) // already be status errors. return toRPCErr(op(cs.attempt)) } - if len(cs.buffer) == 0 { + if len(cs.replayBuffer) == 0 { // For the first op, which controls creation of the stream and // assigns cs.attempt, we need to create a new attempt inline // before executing the first op. On subsequent ops, the attempt @@ -851,25 +862,26 @@ func (cs *clientStream) Trailer() metadata.MD { } func (cs *clientStream) replayBufferLocked(attempt *csAttempt) error { - for _, f := range cs.buffer { - if err := f(attempt); err != nil { + for _, f := range cs.replayBuffer { + if err := f.op(attempt); err != nil { return err } } return nil } -func (cs *clientStream) bufferForRetryLocked(sz int, op func(a *csAttempt) error) { +func (cs *clientStream) bufferForRetryLocked(sz int, op func(a *csAttempt) error, cleanup func()) { // Note: we still will buffer if retry is disabled (for transparent retries). if cs.committed { return } - cs.bufferSize += sz - if cs.bufferSize > cs.callInfo.maxRetryRPCBufferSize { + cs.replayBufferSize += sz + if cs.replayBufferSize > cs.callInfo.maxRetryRPCBufferSize { cs.commitAttemptLocked() + cleanup() return } - cs.buffer = append(cs.buffer, op) + cs.replayBuffer = append(cs.replayBuffer, replayOp{op: op, cleanup: cleanup}) } func (cs *clientStream) SendMsg(m any) (err error) { @@ -891,23 +903,50 @@ func (cs *clientStream) SendMsg(m any) (err error) { } // load hdr, payload, data - hdr, payload, data, err := prepareMsg(m, cs.codec, cs.cp, cs.comp) + hdr, data, payload, pf, err := prepareMsg(m, cs.codec, cs.cp, cs.comp, cs.cc.dopts.copts.BufferPool) if err != nil { return err } + defer func() { + data.Free() + // only free payload if compression was made, and therefore it is a different set + // of buffers from data. + if pf.isCompressed() { + payload.Free() + } + }() + + dataLen := data.Len() + payloadLen := payload.Len() // TODO(dfawley): should we be checking len(data) instead? - if len(payload) > *cs.callInfo.maxSendMessageSize { - return status.Errorf(codes.ResourceExhausted, "trying to send message larger than max (%d vs. %d)", len(payload), *cs.callInfo.maxSendMessageSize) + if payloadLen > *cs.callInfo.maxSendMessageSize { + return status.Errorf(codes.ResourceExhausted, "trying to send message larger than max (%d vs. %d)", payloadLen, *cs.callInfo.maxSendMessageSize) } + + // always take an extra ref in case data == payload (i.e. when the data isn't + // compressed). The original ref will always be freed by the deferred free above. + payload.Ref() op := func(a *csAttempt) error { - return a.sendMsg(m, hdr, payload, data) + return a.sendMsg(m, hdr, payload, dataLen, payloadLen) + } + + // onSuccess is invoked when the op is captured for a subsequent retry. If the + // stream was established by a previous message and therefore retries are + // disabled, onSuccess will not be invoked, and payloadRef can be freed + // immediately. + onSuccessCalled := false + err = cs.withRetry(op, func() { + cs.bufferForRetryLocked(len(hdr)+payloadLen, op, payload.Free) + onSuccessCalled = true + }) + if !onSuccessCalled { + payload.Free() } - err = cs.withRetry(op, func() { cs.bufferForRetryLocked(len(hdr)+len(payload), op) }) if len(cs.binlogs) != 0 && err == nil { cm := &binarylog.ClientMessage{ OnClientSide: true, - Message: data, + Message: data.Materialize(), } for _, binlog := range cs.binlogs { binlog.Log(cs.ctx, cm) @@ -924,6 +963,7 @@ func (cs *clientStream) RecvMsg(m any) error { var recvInfo *payloadInfo if len(cs.binlogs) != 0 { recvInfo = &payloadInfo{} + defer recvInfo.free() } err := cs.withRetry(func(a *csAttempt) error { return a.recvMsg(m, recvInfo) @@ -931,7 +971,7 @@ func (cs *clientStream) RecvMsg(m any) error { if len(cs.binlogs) != 0 && err == nil { sm := &binarylog.ServerMessage{ OnClientSide: true, - Message: recvInfo.uncompressedBytes, + Message: recvInfo.uncompressedBytes.Materialize(), } for _, binlog := range cs.binlogs { binlog.Log(cs.ctx, sm) @@ -958,7 +998,7 @@ func (cs *clientStream) CloseSend() error { // RecvMsg. This also matches historical behavior. return nil } - cs.withRetry(op, func() { cs.bufferForRetryLocked(0, op) }) + cs.withRetry(op, func() { cs.bufferForRetryLocked(0, op, nil) }) if len(cs.binlogs) != 0 { chc := &binarylog.ClientHalfClose{ OnClientSide: true, @@ -1034,7 +1074,7 @@ func (cs *clientStream) finish(err error) { cs.cancel() } -func (a *csAttempt) sendMsg(m any, hdr, payld, data []byte) error { +func (a *csAttempt) sendMsg(m any, hdr []byte, payld mem.BufferSlice, dataLength, payloadLength int) error { cs := a.cs if a.trInfo != nil { a.mu.Lock() @@ -1052,8 +1092,10 @@ func (a *csAttempt) sendMsg(m any, hdr, payld, data []byte) error { } return io.EOF } - for _, sh := range a.statsHandlers { - sh.HandleRPC(a.ctx, outPayload(true, m, data, payld, time.Now())) + if len(a.statsHandlers) != 0 { + for _, sh := range a.statsHandlers { + sh.HandleRPC(a.ctx, outPayload(true, m, dataLength, payloadLength, time.Now())) + } } if channelz.IsOn() { a.t.IncrMsgSent() @@ -1065,6 +1107,7 @@ func (a *csAttempt) recvMsg(m any, payInfo *payloadInfo) (err error) { cs := a.cs if len(a.statsHandlers) != 0 && payInfo == nil { payInfo = &payloadInfo{} + defer payInfo.free() } if !a.decompSet { @@ -1083,8 +1126,7 @@ func (a *csAttempt) recvMsg(m any, payInfo *payloadInfo) (err error) { // Only initialize this state once per stream. a.decompSet = true } - err = recv(a.p, cs.codec, a.s, a.dc, m, *cs.callInfo.maxReceiveMessageSize, payInfo, a.decomp) - if err != nil { + if err := recv(a.p, cs.codec, a.s, a.dc, m, *cs.callInfo.maxReceiveMessageSize, payInfo, a.decomp, false); err != nil { if err == io.EOF { if statusErr := a.s.Status().Err(); statusErr != nil { return statusErr @@ -1103,14 +1145,12 @@ func (a *csAttempt) recvMsg(m any, payInfo *payloadInfo) (err error) { } for _, sh := range a.statsHandlers { sh.HandleRPC(a.ctx, &stats.InPayload{ - Client: true, - RecvTime: time.Now(), - Payload: m, - // TODO truncate large payload. - Data: payInfo.uncompressedBytes, + Client: true, + RecvTime: time.Now(), + Payload: m, WireLength: payInfo.compressedLength + headerLen, CompressedLength: payInfo.compressedLength, - Length: len(payInfo.uncompressedBytes), + Length: payInfo.uncompressedBytes.Len(), }) } if channelz.IsOn() { @@ -1122,14 +1162,12 @@ func (a *csAttempt) recvMsg(m any, payInfo *payloadInfo) (err error) { } // Special handling for non-server-stream rpcs. // This recv expects EOF or errors, so we don't collect inPayload. - err = recv(a.p, cs.codec, a.s, a.dc, m, *cs.callInfo.maxReceiveMessageSize, nil, a.decomp) - if err == nil { - return toRPCErr(errors.New("grpc: client streaming protocol violation: get , want ")) - } - if err == io.EOF { + if err := recv(a.p, cs.codec, a.s, a.dc, m, *cs.callInfo.maxReceiveMessageSize, nil, a.decomp, false); err == io.EOF { return a.s.Status().Err() // non-server streaming Recv returns nil on success + } else if err != nil { + return toRPCErr(err) } - return toRPCErr(err) + return toRPCErr(errors.New("grpc: client streaming protocol violation: get , want ")) } func (a *csAttempt) finish(err error) { @@ -1185,12 +1223,12 @@ func (a *csAttempt) finish(err error) { a.mu.Unlock() } -// newClientStream creates a ClientStream with the specified transport, on the +// newNonRetryClientStream creates a ClientStream with the specified transport, on the // given addrConn. // // It's expected that the given transport is either the same one in addrConn, or // is already closed. To avoid race, transport is specified separately, instead -// of using ac.transpot. +// of using ac.transport. // // Main difference between this and ClientConn.NewStream: // - no retry @@ -1276,7 +1314,7 @@ func newNonRetryClientStream(ctx context.Context, desc *StreamDesc, method strin return nil, err } as.s = s - as.p = &parser{r: s, recvBufferPool: ac.dopts.recvBufferPool} + as.p = &parser{r: s, bufferPool: ac.dopts.copts.BufferPool} ac.incrCallsStarted() if desc != unaryStreamDesc { // Listen on stream context to cleanup when the stream context is @@ -1373,17 +1411,26 @@ func (as *addrConnStream) SendMsg(m any) (err error) { } // load hdr, payload, data - hdr, payld, _, err := prepareMsg(m, as.codec, as.cp, as.comp) + hdr, data, payload, pf, err := prepareMsg(m, as.codec, as.cp, as.comp, as.ac.dopts.copts.BufferPool) if err != nil { return err } + defer func() { + data.Free() + // only free payload if compression was made, and therefore it is a different set + // of buffers from data. + if pf.isCompressed() { + payload.Free() + } + }() + // TODO(dfawley): should we be checking len(data) instead? - if len(payld) > *as.callInfo.maxSendMessageSize { - return status.Errorf(codes.ResourceExhausted, "trying to send message larger than max (%d vs. %d)", len(payld), *as.callInfo.maxSendMessageSize) + if payload.Len() > *as.callInfo.maxSendMessageSize { + return status.Errorf(codes.ResourceExhausted, "trying to send message larger than max (%d vs. %d)", payload.Len(), *as.callInfo.maxSendMessageSize) } - if err := as.t.Write(as.s, hdr, payld, &transport.Options{Last: !as.desc.ClientStreams}); err != nil { + if err := as.t.Write(as.s, hdr, payload, &transport.Options{Last: !as.desc.ClientStreams}); err != nil { if !as.desc.ClientStreams { // For non-client-streaming RPCs, we return nil instead of EOF on error // because the generated code requires it. finish is not called; RecvMsg() @@ -1423,8 +1470,7 @@ func (as *addrConnStream) RecvMsg(m any) (err error) { // Only initialize this state once per stream. as.decompSet = true } - err = recv(as.p, as.codec, as.s, as.dc, m, *as.callInfo.maxReceiveMessageSize, nil, as.decomp) - if err != nil { + if err := recv(as.p, as.codec, as.s, as.dc, m, *as.callInfo.maxReceiveMessageSize, nil, as.decomp, false); err != nil { if err == io.EOF { if statusErr := as.s.Status().Err(); statusErr != nil { return statusErr @@ -1444,14 +1490,12 @@ func (as *addrConnStream) RecvMsg(m any) (err error) { // Special handling for non-server-stream rpcs. // This recv expects EOF or errors, so we don't collect inPayload. - err = recv(as.p, as.codec, as.s, as.dc, m, *as.callInfo.maxReceiveMessageSize, nil, as.decomp) - if err == nil { - return toRPCErr(errors.New("grpc: client streaming protocol violation: get , want ")) - } - if err == io.EOF { + if err := recv(as.p, as.codec, as.s, as.dc, m, *as.callInfo.maxReceiveMessageSize, nil, as.decomp, false); err == io.EOF { return as.s.Status().Err() // non-server streaming Recv returns nil on success + } else if err != nil { + return toRPCErr(err) } - return toRPCErr(err) + return toRPCErr(errors.New("grpc: client streaming protocol violation: get , want ")) } func (as *addrConnStream) finish(err error) { @@ -1645,18 +1689,31 @@ func (ss *serverStream) SendMsg(m any) (err error) { } // load hdr, payload, data - hdr, payload, data, err := prepareMsg(m, ss.codec, ss.cp, ss.comp) + hdr, data, payload, pf, err := prepareMsg(m, ss.codec, ss.cp, ss.comp, ss.p.bufferPool) if err != nil { return err } + defer func() { + data.Free() + // only free payload if compression was made, and therefore it is a different set + // of buffers from data. + if pf.isCompressed() { + payload.Free() + } + }() + + dataLen := data.Len() + payloadLen := payload.Len() + // TODO(dfawley): should we be checking len(data) instead? - if len(payload) > ss.maxSendMessageSize { - return status.Errorf(codes.ResourceExhausted, "trying to send message larger than max (%d vs. %d)", len(payload), ss.maxSendMessageSize) + if payloadLen > ss.maxSendMessageSize { + return status.Errorf(codes.ResourceExhausted, "trying to send message larger than max (%d vs. %d)", payloadLen, ss.maxSendMessageSize) } if err := ss.t.Write(ss.s, hdr, payload, &transport.Options{Last: false}); err != nil { return toRPCErr(err) } + if len(ss.binlogs) != 0 { if !ss.serverHeaderBinlogged { h, _ := ss.s.Header() @@ -1669,7 +1726,7 @@ func (ss *serverStream) SendMsg(m any) (err error) { } } sm := &binarylog.ServerMessage{ - Message: data, + Message: data.Materialize(), } for _, binlog := range ss.binlogs { binlog.Log(ss.ctx, sm) @@ -1677,7 +1734,7 @@ func (ss *serverStream) SendMsg(m any) (err error) { } if len(ss.statsHandler) != 0 { for _, sh := range ss.statsHandler { - sh.HandleRPC(ss.s.Context(), outPayload(false, m, data, payload, time.Now())) + sh.HandleRPC(ss.s.Context(), outPayload(false, m, dataLen, payloadLen, time.Now())) } } return nil @@ -1714,8 +1771,9 @@ func (ss *serverStream) RecvMsg(m any) (err error) { var payInfo *payloadInfo if len(ss.statsHandler) != 0 || len(ss.binlogs) != 0 { payInfo = &payloadInfo{} + defer payInfo.free() } - if err := recv(ss.p, ss.codec, ss.s, ss.dc, m, ss.maxReceiveMessageSize, payInfo, ss.decomp); err != nil { + if err := recv(ss.p, ss.codec, ss.s, ss.dc, m, ss.maxReceiveMessageSize, payInfo, ss.decomp, true); err != nil { if err == io.EOF { if len(ss.binlogs) != 0 { chc := &binarylog.ClientHalfClose{} @@ -1733,11 +1791,9 @@ func (ss *serverStream) RecvMsg(m any) (err error) { if len(ss.statsHandler) != 0 { for _, sh := range ss.statsHandler { sh.HandleRPC(ss.s.Context(), &stats.InPayload{ - RecvTime: time.Now(), - Payload: m, - // TODO truncate large payload. - Data: payInfo.uncompressedBytes, - Length: len(payInfo.uncompressedBytes), + RecvTime: time.Now(), + Payload: m, + Length: payInfo.uncompressedBytes.Len(), WireLength: payInfo.compressedLength + headerLen, CompressedLength: payInfo.compressedLength, }) @@ -1745,7 +1801,7 @@ func (ss *serverStream) RecvMsg(m any) (err error) { } if len(ss.binlogs) != 0 { cm := &binarylog.ClientMessage{ - Message: payInfo.uncompressedBytes, + Message: payInfo.uncompressedBytes.Materialize(), } for _, binlog := range ss.binlogs { binlog.Log(ss.ctx, cm) @@ -1760,23 +1816,26 @@ func MethodFromServerStream(stream ServerStream) (string, bool) { return Method(stream.Context()) } -// prepareMsg returns the hdr, payload and data -// using the compressors passed or using the -// passed preparedmsg -func prepareMsg(m any, codec baseCodec, cp Compressor, comp encoding.Compressor) (hdr, payload, data []byte, err error) { +// prepareMsg returns the hdr, payload and data using the compressors passed or +// using the passed preparedmsg. The returned boolean indicates whether +// compression was made and therefore whether the payload needs to be freed in +// addition to the returned data. Freeing the payload if the returned boolean is +// false can lead to undefined behavior. +func prepareMsg(m any, codec baseCodec, cp Compressor, comp encoding.Compressor, pool mem.BufferPool) (hdr []byte, data, payload mem.BufferSlice, pf payloadFormat, err error) { if preparedMsg, ok := m.(*PreparedMsg); ok { - return preparedMsg.hdr, preparedMsg.payload, preparedMsg.encodedData, nil + return preparedMsg.hdr, preparedMsg.encodedData, preparedMsg.payload, preparedMsg.pf, nil } // The input interface is not a prepared msg. // Marshal and Compress the data at this point data, err = encode(codec, m) if err != nil { - return nil, nil, nil, err + return nil, nil, nil, 0, err } - compData, err := compress(data, cp, comp) + compData, pf, err := compress(data, cp, comp, pool) if err != nil { - return nil, nil, nil, err + data.Free() + return nil, nil, nil, 0, err } - hdr, payload = msgHeader(data, compData) - return hdr, payload, data, nil + hdr, payload = msgHeader(data, compData, pf) + return hdr, data, payload, pf, nil } diff --git a/go-controller/vendor/google.golang.org/grpc/stream_interfaces.go b/go-controller/vendor/google.golang.org/grpc/stream_interfaces.go index 8b813529c0..0037fee0bd 100644 --- a/go-controller/vendor/google.golang.org/grpc/stream_interfaces.go +++ b/go-controller/vendor/google.golang.org/grpc/stream_interfaces.go @@ -22,15 +22,35 @@ package grpc // request, many responses) RPC. It is generic over the type of the response // message. It is used in generated code. type ServerStreamingClient[Res any] interface { + // Recv receives the next response message from the server. The client may + // repeatedly call Recv to read messages from the response stream. If + // io.EOF is returned, the stream has terminated with an OK status. Any + // other error is compatible with the status package and indicates the + // RPC's status code and message. Recv() (*Res, error) + + // ClientStream is embedded to provide Context, Header, and Trailer + // functionality. No other methods in the ClientStream should be called + // directly. ClientStream } // ServerStreamingServer represents the server side of a server-streaming (one // request, many responses) RPC. It is generic over the type of the response // message. It is used in generated code. +// +// To terminate the response stream, return from the handler method and return +// an error from the status package, or use nil to indicate an OK status code. type ServerStreamingServer[Res any] interface { + // Send sends a response message to the client. The server handler may + // call Send multiple times to send multiple messages to the client. An + // error is returned if the stream was terminated unexpectedly, and the + // handler method should return, as the stream is no longer usable. Send(*Res) error + + // ServerStream is embedded to provide Context, SetHeader, SendHeader, and + // SetTrailer functionality. No other methods in the ServerStream should + // be called directly. ServerStream } @@ -39,8 +59,22 @@ type ServerStreamingServer[Res any] interface { // message stream and the type of the unary response message. It is used in // generated code. type ClientStreamingClient[Req any, Res any] interface { + // Send sends a request message to the server. The client may call Send + // multiple times to send multiple messages to the server. On error, Send + // aborts the stream. If the error was generated by the client, the status + // is returned directly. Otherwise, io.EOF is returned, and the status of + // the stream may be discovered using CloseAndRecv(). Send(*Req) error + + // CloseAndRecv closes the request stream and waits for the server's + // response. This method must be called once and only once after sending + // all request messages. Any error returned is implemented by the status + // package. CloseAndRecv() (*Res, error) + + // ClientStream is embedded to provide Context, Header, and Trailer + // functionality. No other methods in the ClientStream should be called + // directly. ClientStream } @@ -48,9 +82,28 @@ type ClientStreamingClient[Req any, Res any] interface { // requests, one response) RPC. It is generic over both the type of the request // message stream and the type of the unary response message. It is used in // generated code. +// +// To terminate the RPC, call SendAndClose and return nil from the method +// handler or do not call SendAndClose and return an error from the status +// package. type ClientStreamingServer[Req any, Res any] interface { + // Recv receives the next request message from the client. The server may + // repeatedly call Recv to read messages from the request stream. If + // io.EOF is returned, it indicates the client called CloseAndRecv on its + // ClientStreamingClient. Any other error indicates the stream was + // terminated unexpectedly, and the handler method should return, as the + // stream is no longer usable. Recv() (*Req, error) + + // SendAndClose sends a single response message to the client and closes + // the stream. This method must be called once and only once after all + // request messages have been processed. Recv should not be called after + // calling SendAndClose. SendAndClose(*Res) error + + // ServerStream is embedded to provide Context, SetHeader, SendHeader, and + // SetTrailer functionality. No other methods in the ServerStream should + // be called directly. ServerStream } @@ -59,8 +112,23 @@ type ClientStreamingServer[Req any, Res any] interface { // request message stream and the type of the response message stream. It is // used in generated code. type BidiStreamingClient[Req any, Res any] interface { + // Send sends a request message to the server. The client may call Send + // multiple times to send multiple messages to the server. On error, Send + // aborts the stream. If the error was generated by the client, the status + // is returned directly. Otherwise, io.EOF is returned, and the status of + // the stream may be discovered using Recv(). Send(*Req) error + + // Recv receives the next response message from the server. The client may + // repeatedly call Recv to read messages from the response stream. If + // io.EOF is returned, the stream has terminated with an OK status. Any + // other error is compatible with the status package and indicates the + // RPC's status code and message. Recv() (*Res, error) + + // ClientStream is embedded to provide Context, Header, Trailer, and + // CloseSend functionality. No other methods in the ClientStream should be + // called directly. ClientStream } @@ -68,9 +136,27 @@ type BidiStreamingClient[Req any, Res any] interface { // (many requests, many responses) RPC. It is generic over both the type of the // request message stream and the type of the response message stream. It is // used in generated code. +// +// To terminate the stream, return from the handler method and return +// an error from the status package, or use nil to indicate an OK status code. type BidiStreamingServer[Req any, Res any] interface { + // Recv receives the next request message from the client. The server may + // repeatedly call Recv to read messages from the request stream. If + // io.EOF is returned, it indicates the client called CloseSend on its + // BidiStreamingClient. Any other error indicates the stream was + // terminated unexpectedly, and the handler method should return, as the + // stream is no longer usable. Recv() (*Req, error) + + // Send sends a response message to the client. The server handler may + // call Send multiple times to send multiple messages to the client. An + // error is returned if the stream was terminated unexpectedly, and the + // handler method should return, as the stream is no longer usable. Send(*Res) error + + // ServerStream is embedded to provide Context, SetHeader, SendHeader, and + // SetTrailer functionality. No other methods in the ServerStream should + // be called directly. ServerStream } diff --git a/go-controller/vendor/google.golang.org/grpc/version.go b/go-controller/vendor/google.golang.org/grpc/version.go index bafaef99be..5a47094ae8 100644 --- a/go-controller/vendor/google.golang.org/grpc/version.go +++ b/go-controller/vendor/google.golang.org/grpc/version.go @@ -19,4 +19,4 @@ package grpc // Version is the current grpc version. -const Version = "1.65.0" +const Version = "1.68.1" diff --git a/go-controller/vendor/google.golang.org/protobuf/encoding/protojson/decode.go b/go-controller/vendor/google.golang.org/protobuf/encoding/protojson/decode.go index 8f9e592f87..737d6876d5 100644 --- a/go-controller/vendor/google.golang.org/protobuf/encoding/protojson/decode.go +++ b/go-controller/vendor/google.golang.org/protobuf/encoding/protojson/decode.go @@ -192,11 +192,6 @@ func (d decoder) unmarshalMessage(m protoreflect.Message, skipTypeURL bool) erro fd = fieldDescs.ByTextName(name) } } - if flags.ProtoLegacy { - if fd != nil && fd.IsWeak() && fd.Message().IsPlaceholder() { - fd = nil // reset since the weak reference is not linked in - } - } if fd == nil { // Field is unknown. diff --git a/go-controller/vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go b/go-controller/vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go index 4b177c8206..e9fe103943 100644 --- a/go-controller/vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go +++ b/go-controller/vendor/google.golang.org/protobuf/encoding/protojson/well_known_types.go @@ -348,7 +348,11 @@ func (d decoder) unmarshalAnyValue(unmarshal unmarshalFunc, m protoreflect.Messa switch tok.Kind() { case json.ObjectClose: if !found { - return d.newError(tok.Pos(), `missing "value" field`) + // We tolerate an omitted `value` field with the google.protobuf.Empty Well-Known-Type, + // for compatibility with other proto runtimes that have interpreted the spec differently. + if m.Descriptor().FullName() != genid.Empty_message_fullname { + return d.newError(tok.Pos(), `missing "value" field`) + } } return nil diff --git a/go-controller/vendor/google.golang.org/protobuf/encoding/prototext/decode.go b/go-controller/vendor/google.golang.org/protobuf/encoding/prototext/decode.go index 24bc98ac42..b53805056a 100644 --- a/go-controller/vendor/google.golang.org/protobuf/encoding/prototext/decode.go +++ b/go-controller/vendor/google.golang.org/protobuf/encoding/prototext/decode.go @@ -185,11 +185,6 @@ func (d decoder) unmarshalMessage(m protoreflect.Message, checkDelims bool) erro } else if xtErr != nil && xtErr != protoregistry.NotFound { return d.newError(tok.Pos(), "unable to resolve [%s]: %v", tok.RawString(), xtErr) } - if flags.ProtoLegacy { - if fd != nil && fd.IsWeak() && fd.Message().IsPlaceholder() { - fd = nil // reset since the weak reference is not linked in - } - } // Handle unknown fields. if fd == nil { diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/editiondefaults/editions_defaults.binpb b/go-controller/vendor/google.golang.org/protobuf/internal/editiondefaults/editions_defaults.binpb index ff6a38360add36f53d48bb0863b701696e0d7b2d..5a57ef6f3c80a4a930b7bdb33b039ea94d1eb5f2 100644 GIT binary patch literal 138 zcmd;*muO*EV!mX@pe4$|D8MAaq`<7fXux#Ijt$6VkYMDJmv|0Wz$CyZ!KlClRKN&Q wzyMY7f?Y`%s2WL*1th1%ddZFnY{E-+C6MVz3P75fB^b3pHY+@1*LcYe04AXnGXMYp literal 93 zcmd;*mUzal#C*w)K}(Q>QGiK;Nr72|(SYfa9TNv5m$bxlxFnMRqXeS@6Ht;7B*_4j Ve8H{+(u69m1u{(G8N0>{b^xZ!4_5#H diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/editionssupport/editions.go b/go-controller/vendor/google.golang.org/protobuf/internal/editionssupport/editions.go deleted file mode 100644 index 08dad7692c..0000000000 --- a/go-controller/vendor/google.golang.org/protobuf/internal/editionssupport/editions.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2024 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package editionssupport defines constants for editions that are supported. -package editionssupport - -import "google.golang.org/protobuf/types/descriptorpb" - -const ( - Minimum = descriptorpb.Edition_EDITION_PROTO2 - Maximum = descriptorpb.Edition_EDITION_2023 -) diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/encoding/tag/tag.go b/go-controller/vendor/google.golang.org/protobuf/internal/encoding/tag/tag.go index 7e87c76044..669133d04d 100644 --- a/go-controller/vendor/google.golang.org/protobuf/internal/encoding/tag/tag.go +++ b/go-controller/vendor/google.golang.org/protobuf/internal/encoding/tag/tag.go @@ -26,7 +26,7 @@ var byteType = reflect.TypeOf(byte(0)) // The type is the underlying field type (e.g., a repeated field may be // represented by []T, but the Go type passed in is just T). // A list of enum value descriptors must be provided for enum fields. -// This does not populate the Enum or Message (except for weak message). +// This does not populate the Enum or Message. // // This function is a best effort attempt; parsing errors are ignored. func Unmarshal(tag string, goType reflect.Type, evs protoreflect.EnumValueDescriptors) protoreflect.FieldDescriptor { @@ -109,9 +109,6 @@ func Unmarshal(tag string, goType reflect.Type, evs protoreflect.EnumValueDescri } case s == "packed": f.L1.EditionFeatures.IsPacked = true - case strings.HasPrefix(s, "weak="): - f.L1.IsWeak = true - f.L1.Message = filedesc.PlaceholderMessage(protoreflect.FullName(s[len("weak="):])) case strings.HasPrefix(s, "def="): // The default tag is special in that everything afterwards is the // default regardless of the presence of commas. @@ -183,9 +180,6 @@ func Marshal(fd protoreflect.FieldDescriptor, enumName string) string { // the exact same semantics from the previous generator. tag = append(tag, "json="+jsonName) } - if fd.IsWeak() { - tag = append(tag, "weak="+string(fd.Message().FullName())) - } // The previous implementation does not tag extension fields as proto3, // even when the field is defined in a proto3 file. Match that behavior // for consistency. diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/errors/is_go112.go b/go-controller/vendor/google.golang.org/protobuf/internal/errors/is_go112.go deleted file mode 100644 index fbcd349207..0000000000 --- a/go-controller/vendor/google.golang.org/protobuf/internal/errors/is_go112.go +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !go1.13 -// +build !go1.13 - -package errors - -import "reflect" - -// Is is a copy of Go 1.13's errors.Is for use with older Go versions. -func Is(err, target error) bool { - if target == nil { - return err == target - } - - isComparable := reflect.TypeOf(target).Comparable() - for { - if isComparable && err == target { - return true - } - if x, ok := err.(interface{ Is(error) bool }); ok && x.Is(target) { - return true - } - if err = unwrap(err); err == nil { - return false - } - } -} - -func unwrap(err error) error { - u, ok := err.(interface { - Unwrap() error - }) - if !ok { - return nil - } - return u.Unwrap() -} diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/errors/is_go113.go b/go-controller/vendor/google.golang.org/protobuf/internal/errors/is_go113.go deleted file mode 100644 index 5e72f1cde9..0000000000 --- a/go-controller/vendor/google.golang.org/protobuf/internal/errors/is_go113.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build go1.13 -// +build go1.13 - -package errors - -import "errors" - -// Is is errors.Is. -func Is(err, target error) bool { return errors.Is(err, target) } diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/filedesc/desc.go b/go-controller/vendor/google.golang.org/protobuf/internal/filedesc/desc.go index fa790e0ff1..688aabe434 100644 --- a/go-controller/vendor/google.golang.org/protobuf/internal/filedesc/desc.go +++ b/go-controller/vendor/google.golang.org/protobuf/internal/filedesc/desc.go @@ -19,7 +19,6 @@ import ( "google.golang.org/protobuf/internal/pragma" "google.golang.org/protobuf/internal/strs" "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/reflect/protoregistry" ) // Edition is an Enum for proto2.Edition @@ -32,6 +31,7 @@ const ( EditionProto2 Edition = 998 EditionProto3 Edition = 999 Edition2023 Edition = 1000 + Edition2024 Edition = 1001 EditionUnsupported Edition = 100000 ) @@ -77,31 +77,48 @@ type ( Locations SourceLocations } + // EditionFeatures is a frequently-instantiated struct, so please take care + // to minimize padding when adding new fields to this struct (add them in + // the right place/order). EditionFeatures struct { + // StripEnumPrefix determines if the plugin generates enum value + // constants as-is, with their prefix stripped, or both variants. + StripEnumPrefix int + // IsFieldPresence is true if field_presence is EXPLICIT // https://protobuf.dev/editions/features/#field_presence IsFieldPresence bool + // IsFieldPresence is true if field_presence is LEGACY_REQUIRED // https://protobuf.dev/editions/features/#field_presence IsLegacyRequired bool + // IsOpenEnum is true if enum_type is OPEN // https://protobuf.dev/editions/features/#enum_type IsOpenEnum bool + // IsPacked is true if repeated_field_encoding is PACKED // https://protobuf.dev/editions/features/#repeated_field_encoding IsPacked bool + // IsUTF8Validated is true if utf_validation is VERIFY // https://protobuf.dev/editions/features/#utf8_validation IsUTF8Validated bool + // IsDelimitedEncoded is true if message_encoding is DELIMITED // https://protobuf.dev/editions/features/#message_encoding IsDelimitedEncoded bool + // IsJSONCompliant is true if json_format is ALLOW // https://protobuf.dev/editions/features/#json_format IsJSONCompliant bool + // GenerateLegacyUnmarshalJSON determines if the plugin generates the // UnmarshalJSON([]byte) error method for enums. GenerateLegacyUnmarshalJSON bool + // APILevel controls which API (Open, Hybrid or Opaque) should be used + // for generated code (.pb.go files). + APILevel int } ) @@ -257,7 +274,6 @@ type ( Kind protoreflect.Kind StringName stringName IsProto3Optional bool // promoted from google.protobuf.FieldDescriptorProto - IsWeak bool // promoted from google.protobuf.FieldOptions IsLazy bool // promoted from google.protobuf.FieldOptions Default defaultValue ContainingOneof protoreflect.OneofDescriptor // must be consistent with Message.Oneofs.Fields @@ -351,7 +367,7 @@ func (fd *Field) IsPacked() bool { return fd.L1.EditionFeatures.IsPacked } func (fd *Field) IsExtension() bool { return false } -func (fd *Field) IsWeak() bool { return fd.L1.IsWeak } +func (fd *Field) IsWeak() bool { return false } func (fd *Field) IsLazy() bool { return fd.L1.IsLazy } func (fd *Field) IsList() bool { return fd.Cardinality() == protoreflect.Repeated && !fd.IsMap() } func (fd *Field) IsMap() bool { return fd.Message() != nil && fd.Message().IsMapEntry() } @@ -378,11 +394,6 @@ func (fd *Field) Enum() protoreflect.EnumDescriptor { return fd.L1.Enum } func (fd *Field) Message() protoreflect.MessageDescriptor { - if fd.L1.IsWeak { - if d, _ := protoregistry.GlobalFiles.FindDescriptorByName(fd.L1.Message.FullName()); d != nil { - return d.(protoreflect.MessageDescriptor) - } - } return fd.L1.Message } func (fd *Field) IsMapEntry() bool { diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/filedesc/desc_lazy.go b/go-controller/vendor/google.golang.org/protobuf/internal/filedesc/desc_lazy.go index 67a51b327c..d4c94458bd 100644 --- a/go-controller/vendor/google.golang.org/protobuf/internal/filedesc/desc_lazy.go +++ b/go-controller/vendor/google.golang.org/protobuf/internal/filedesc/desc_lazy.go @@ -32,11 +32,6 @@ func (file *File) resolveMessages() { for j := range md.L2.Fields.List { fd := &md.L2.Fields.List[j] - // Weak fields are resolved upon actual use. - if fd.L1.IsWeak { - continue - } - // Resolve message field dependency. switch fd.L1.Kind { case protoreflect.EnumKind: @@ -150,8 +145,6 @@ func (fd *File) unmarshalFull(b []byte) { switch num { case genid.FileDescriptorProto_PublicDependency_field_number: fd.L2.Imports[v].IsPublic = true - case genid.FileDescriptorProto_WeakDependency_field_number: - fd.L2.Imports[v].IsWeak = true } case protowire.BytesType: v, m := protowire.ConsumeBytes(b) @@ -502,8 +495,6 @@ func (fd *Field) unmarshalOptions(b []byte) { switch num { case genid.FieldOptions_Packed_field_number: fd.L1.EditionFeatures.IsPacked = protowire.DecodeBool(v) - case genid.FieldOptions_Weak_field_number: - fd.L1.IsWeak = protowire.DecodeBool(v) case genid.FieldOptions_Lazy_field_number: fd.L1.IsLazy = protowire.DecodeBool(v) case FieldOptions_EnforceUTF8: diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/filedesc/editions.go b/go-controller/vendor/google.golang.org/protobuf/internal/filedesc/editions.go index fd4d0c83d2..10132c9b38 100644 --- a/go-controller/vendor/google.golang.org/protobuf/internal/filedesc/editions.go +++ b/go-controller/vendor/google.golang.org/protobuf/internal/filedesc/editions.go @@ -32,6 +32,14 @@ func unmarshalGoFeature(b []byte, parent EditionFeatures) EditionFeatures { v, m := protowire.ConsumeVarint(b) b = b[m:] parent.GenerateLegacyUnmarshalJSON = protowire.DecodeBool(v) + case genid.GoFeatures_ApiLevel_field_number: + v, m := protowire.ConsumeVarint(b) + b = b[m:] + parent.APILevel = int(v) + case genid.GoFeatures_StripEnumPrefix_field_number: + v, m := protowire.ConsumeVarint(b) + b = b[m:] + parent.StripEnumPrefix = int(v) default: panic(fmt.Sprintf("unkown field number %d while unmarshalling GoFeatures", num)) } diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/filetype/build.go b/go-controller/vendor/google.golang.org/protobuf/internal/filetype/build.go index ba83fea44c..e1b4130bd2 100644 --- a/go-controller/vendor/google.golang.org/protobuf/internal/filetype/build.go +++ b/go-controller/vendor/google.golang.org/protobuf/internal/filetype/build.go @@ -63,7 +63,7 @@ type Builder struct { // message declarations in "flattened ordering". // // Dependencies are Go types for enums or messages referenced by - // message fields (excluding weak fields), for parent extended messages of + // message fields, for parent extended messages of // extension fields, for enums or messages referenced by extension fields, // and for input and output messages referenced by service methods. // Dependencies must come after declarations, but the ordering of diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/flags/flags.go b/go-controller/vendor/google.golang.org/protobuf/internal/flags/flags.go index 58372dd348..a06ccabc2f 100644 --- a/go-controller/vendor/google.golang.org/protobuf/internal/flags/flags.go +++ b/go-controller/vendor/google.golang.org/protobuf/internal/flags/flags.go @@ -6,7 +6,7 @@ package flags // ProtoLegacy specifies whether to enable support for legacy functionality -// such as MessageSets, weak fields, and various other obscure behavior +// such as MessageSets, and various other obscure behavior // that is necessary to maintain backwards compatibility with proto1 or // the pre-release variants of proto2 and proto3. // diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/genid/go_features_gen.go b/go-controller/vendor/google.golang.org/protobuf/internal/genid/go_features_gen.go index 7f67cbb6e9..f5ee7f5c2b 100644 --- a/go-controller/vendor/google.golang.org/protobuf/internal/genid/go_features_gen.go +++ b/go-controller/vendor/google.golang.org/protobuf/internal/genid/go_features_gen.go @@ -21,13 +21,47 @@ const ( // Field names for pb.GoFeatures. const ( GoFeatures_LegacyUnmarshalJsonEnum_field_name protoreflect.Name = "legacy_unmarshal_json_enum" + GoFeatures_ApiLevel_field_name protoreflect.Name = "api_level" + GoFeatures_StripEnumPrefix_field_name protoreflect.Name = "strip_enum_prefix" GoFeatures_LegacyUnmarshalJsonEnum_field_fullname protoreflect.FullName = "pb.GoFeatures.legacy_unmarshal_json_enum" + GoFeatures_ApiLevel_field_fullname protoreflect.FullName = "pb.GoFeatures.api_level" + GoFeatures_StripEnumPrefix_field_fullname protoreflect.FullName = "pb.GoFeatures.strip_enum_prefix" ) // Field numbers for pb.GoFeatures. const ( GoFeatures_LegacyUnmarshalJsonEnum_field_number protoreflect.FieldNumber = 1 + GoFeatures_ApiLevel_field_number protoreflect.FieldNumber = 2 + GoFeatures_StripEnumPrefix_field_number protoreflect.FieldNumber = 3 +) + +// Full and short names for pb.GoFeatures.APILevel. +const ( + GoFeatures_APILevel_enum_fullname = "pb.GoFeatures.APILevel" + GoFeatures_APILevel_enum_name = "APILevel" +) + +// Enum values for pb.GoFeatures.APILevel. +const ( + GoFeatures_API_LEVEL_UNSPECIFIED_enum_value = 0 + GoFeatures_API_OPEN_enum_value = 1 + GoFeatures_API_HYBRID_enum_value = 2 + GoFeatures_API_OPAQUE_enum_value = 3 +) + +// Full and short names for pb.GoFeatures.StripEnumPrefix. +const ( + GoFeatures_StripEnumPrefix_enum_fullname = "pb.GoFeatures.StripEnumPrefix" + GoFeatures_StripEnumPrefix_enum_name = "StripEnumPrefix" +) + +// Enum values for pb.GoFeatures.StripEnumPrefix. +const ( + GoFeatures_STRIP_ENUM_PREFIX_UNSPECIFIED_enum_value = 0 + GoFeatures_STRIP_ENUM_PREFIX_KEEP_enum_value = 1 + GoFeatures_STRIP_ENUM_PREFIX_GENERATE_BOTH_enum_value = 2 + GoFeatures_STRIP_ENUM_PREFIX_STRIP_enum_value = 3 ) // Extension numbers diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/genid/goname.go b/go-controller/vendor/google.golang.org/protobuf/internal/genid/goname.go index 693d2e9e1f..99bb95bafd 100644 --- a/go-controller/vendor/google.golang.org/protobuf/internal/genid/goname.go +++ b/go-controller/vendor/google.golang.org/protobuf/internal/genid/goname.go @@ -11,15 +11,10 @@ const ( SizeCache_goname = "sizeCache" SizeCacheA_goname = "XXX_sizecache" - WeakFields_goname = "weakFields" - WeakFieldsA_goname = "XXX_weak" - UnknownFields_goname = "unknownFields" UnknownFieldsA_goname = "XXX_unrecognized" ExtensionFields_goname = "extensionFields" ExtensionFieldsA_goname = "XXX_InternalExtensions" ExtensionFieldsB_goname = "XXX_extensions" - - WeakFieldPrefix_goname = "XXX_weak_" ) diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/genid/name.go b/go-controller/vendor/google.golang.org/protobuf/internal/genid/name.go new file mode 100644 index 0000000000..224f339302 --- /dev/null +++ b/go-controller/vendor/google.golang.org/protobuf/internal/genid/name.go @@ -0,0 +1,12 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package genid + +const ( + NoUnkeyedLiteral_goname = "noUnkeyedLiteral" + NoUnkeyedLiteralA_goname = "XXX_NoUnkeyedLiteral" + + BuilderSuffix_goname = "_builder" +) diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/impl/api_export_opaque.go b/go-controller/vendor/google.golang.org/protobuf/internal/impl/api_export_opaque.go new file mode 100644 index 0000000000..6075d6f696 --- /dev/null +++ b/go-controller/vendor/google.golang.org/protobuf/internal/impl/api_export_opaque.go @@ -0,0 +1,128 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package impl + +import ( + "strconv" + "sync/atomic" + "unsafe" + + "google.golang.org/protobuf/reflect/protoreflect" +) + +func (Export) UnmarshalField(msg any, fieldNum int32) { + UnmarshalField(msg.(protoreflect.ProtoMessage).ProtoReflect(), protoreflect.FieldNumber(fieldNum)) +} + +// Present checks the presence set for a certain field number (zero +// based, ordered by appearance in original proto file). part is +// a pointer to the correct element in the bitmask array, num is the +// field number unaltered. Example (field number 70 -> part = +// &m.XXX_presence[1], num = 70) +func (Export) Present(part *uint32, num uint32) bool { + // This hook will read an unprotected shadow presence set if + // we're unning under the race detector + raceDetectHookPresent(part, num) + return atomic.LoadUint32(part)&(1<<(num%32)) > 0 +} + +// SetPresent adds a field to the presence set. part is a pointer to +// the relevant element in the array and num is the field number +// unaltered. size is the number of fields in the protocol +// buffer. +func (Export) SetPresent(part *uint32, num uint32, size uint32) { + // This hook will mutate an unprotected shadow presence set if + // we're running under the race detector + raceDetectHookSetPresent(part, num, presenceSize(size)) + for { + old := atomic.LoadUint32(part) + if atomic.CompareAndSwapUint32(part, old, old|(1<<(num%32))) { + return + } + } +} + +// SetPresentNonAtomic is like SetPresent, but operates non-atomically. +// It is meant for use by builder methods, where the message is known not +// to be accessible yet by other goroutines. +func (Export) SetPresentNonAtomic(part *uint32, num uint32, size uint32) { + // This hook will mutate an unprotected shadow presence set if + // we're running under the race detector + raceDetectHookSetPresent(part, num, presenceSize(size)) + *part |= 1 << (num % 32) +} + +// ClearPresence removes a field from the presence set. part is a +// pointer to the relevant element in the presence array and num is +// the field number unaltered. +func (Export) ClearPresent(part *uint32, num uint32) { + // This hook will mutate an unprotected shadow presence set if + // we're running under the race detector + raceDetectHookClearPresent(part, num) + for { + old := atomic.LoadUint32(part) + if atomic.CompareAndSwapUint32(part, old, old&^(1<<(num%32))) { + return + } + } +} + +// interfaceToPointer takes a pointer to an empty interface whose value is a +// pointer type, and converts it into a "pointer" that points to the same +// target +func interfaceToPointer(i *any) pointer { + return pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]} +} + +func (p pointer) atomicGetPointer() pointer { + return pointer{p: atomic.LoadPointer((*unsafe.Pointer)(p.p))} +} + +func (p pointer) atomicSetPointer(q pointer) { + atomic.StorePointer((*unsafe.Pointer)(p.p), q.p) +} + +// AtomicCheckPointerIsNil takes an interface (which is a pointer to a +// pointer) and returns true if the pointed-to pointer is nil (using an +// atomic load). This function is inlineable and, on x86, just becomes a +// simple load and compare. +func (Export) AtomicCheckPointerIsNil(ptr any) bool { + return interfaceToPointer(&ptr).atomicGetPointer().IsNil() +} + +// AtomicSetPointer takes two interfaces (first is a pointer to a pointer, +// second is a pointer) and atomically sets the second pointer into location +// referenced by first pointer. Unfortunately, atomicSetPointer() does not inline +// (even on x86), so this does not become a simple store on x86. +func (Export) AtomicSetPointer(dstPtr, valPtr any) { + interfaceToPointer(&dstPtr).atomicSetPointer(interfaceToPointer(&valPtr)) +} + +// AtomicLoadPointer loads the pointer at the location pointed at by src, +// and stores that pointer value into the location pointed at by dst. +func (Export) AtomicLoadPointer(ptr Pointer, dst Pointer) { + *(*unsafe.Pointer)(unsafe.Pointer(dst)) = atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(ptr))) +} + +// AtomicInitializePointer makes ptr and dst point to the same value. +// +// If *ptr is a nil pointer, it sets *ptr = *dst. +// +// If *ptr is a non-nil pointer, it sets *dst = *ptr. +func (Export) AtomicInitializePointer(ptr Pointer, dst Pointer) { + if !atomic.CompareAndSwapPointer((*unsafe.Pointer)(ptr), unsafe.Pointer(nil), *(*unsafe.Pointer)(dst)) { + *(*unsafe.Pointer)(unsafe.Pointer(dst)) = atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(ptr))) + } +} + +// MessageFieldStringOf returns the field formatted as a string, +// either as the field name if resolvable otherwise as a decimal string. +func (Export) MessageFieldStringOf(md protoreflect.MessageDescriptor, n protoreflect.FieldNumber) string { + fd := md.Fields().ByNumber(n) + if fd != nil { + return string(fd.Name()) + } + return strconv.Itoa(int(n)) +} diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/impl/bitmap.go b/go-controller/vendor/google.golang.org/protobuf/internal/impl/bitmap.go new file mode 100644 index 0000000000..ea276547cd --- /dev/null +++ b/go-controller/vendor/google.golang.org/protobuf/internal/impl/bitmap.go @@ -0,0 +1,34 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !race + +package impl + +// There is no additional data as we're not running under race detector. +type RaceDetectHookData struct{} + +// Empty stubs for when not using the race detector. Calls to these from index.go should be optimized away. +func (presence) raceDetectHookPresent(num uint32) {} +func (presence) raceDetectHookSetPresent(num uint32, size presenceSize) {} +func (presence) raceDetectHookClearPresent(num uint32) {} +func (presence) raceDetectHookAllocAndCopy(src presence) {} + +// raceDetectHookPresent is called by the generated file interface +// (*proto.internalFuncs) Present to optionally read an unprotected +// shadow bitmap when race detection is enabled. In regular code it is +// a noop. +func raceDetectHookPresent(field *uint32, num uint32) {} + +// raceDetectHookSetPresent is called by the generated file interface +// (*proto.internalFuncs) SetPresent to optionally write an unprotected +// shadow bitmap when race detection is enabled. In regular code it is +// a noop. +func raceDetectHookSetPresent(field *uint32, num uint32, size presenceSize) {} + +// raceDetectHookClearPresent is called by the generated file interface +// (*proto.internalFuncs) ClearPresent to optionally write an unprotected +// shadow bitmap when race detection is enabled. In regular code it is +// a noop. +func raceDetectHookClearPresent(field *uint32, num uint32) {} diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/impl/bitmap_race.go b/go-controller/vendor/google.golang.org/protobuf/internal/impl/bitmap_race.go new file mode 100644 index 0000000000..e9a27583ae --- /dev/null +++ b/go-controller/vendor/google.golang.org/protobuf/internal/impl/bitmap_race.go @@ -0,0 +1,126 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build race + +package impl + +// When running under race detector, we add a presence map of bytes, that we can access +// in the hook functions so that we trigger the race detection whenever we have concurrent +// Read-Writes or Write-Writes. The race detector does not otherwise detect invalid concurrent +// access to lazy fields as all updates of bitmaps and pointers are done using atomic operations. +type RaceDetectHookData struct { + shadowPresence *[]byte +} + +// Hooks for presence bitmap operations that allocate, read and write the shadowPresence +// using non-atomic operations. +func (data *RaceDetectHookData) raceDetectHookAlloc(size presenceSize) { + sp := make([]byte, size) + atomicStoreShadowPresence(&data.shadowPresence, &sp) +} + +func (p presence) raceDetectHookPresent(num uint32) { + data := p.toRaceDetectData() + if data == nil { + return + } + sp := atomicLoadShadowPresence(&data.shadowPresence) + if sp != nil { + _ = (*sp)[num] + } +} + +func (p presence) raceDetectHookSetPresent(num uint32, size presenceSize) { + data := p.toRaceDetectData() + if data == nil { + return + } + sp := atomicLoadShadowPresence(&data.shadowPresence) + if sp == nil { + data.raceDetectHookAlloc(size) + sp = atomicLoadShadowPresence(&data.shadowPresence) + } + (*sp)[num] = 1 +} + +func (p presence) raceDetectHookClearPresent(num uint32) { + data := p.toRaceDetectData() + if data == nil { + return + } + sp := atomicLoadShadowPresence(&data.shadowPresence) + if sp != nil { + (*sp)[num] = 0 + + } +} + +// raceDetectHookAllocAndCopy allocates a new shadowPresence slice at lazy and copies +// shadowPresence bytes from src to lazy. +func (p presence) raceDetectHookAllocAndCopy(q presence) { + sData := q.toRaceDetectData() + dData := p.toRaceDetectData() + if sData == nil { + return + } + srcSp := atomicLoadShadowPresence(&sData.shadowPresence) + if srcSp == nil { + atomicStoreShadowPresence(&dData.shadowPresence, nil) + return + } + n := len(*srcSp) + dSlice := make([]byte, n) + atomicStoreShadowPresence(&dData.shadowPresence, &dSlice) + for i := 0; i < n; i++ { + dSlice[i] = (*srcSp)[i] + } +} + +// raceDetectHookPresent is called by the generated file interface +// (*proto.internalFuncs) Present to optionally read an unprotected +// shadow bitmap when race detection is enabled. In regular code it is +// a noop. +func raceDetectHookPresent(field *uint32, num uint32) { + data := findPointerToRaceDetectData(field, num) + if data == nil { + return + } + sp := atomicLoadShadowPresence(&data.shadowPresence) + if sp != nil { + _ = (*sp)[num] + } +} + +// raceDetectHookSetPresent is called by the generated file interface +// (*proto.internalFuncs) SetPresent to optionally write an unprotected +// shadow bitmap when race detection is enabled. In regular code it is +// a noop. +func raceDetectHookSetPresent(field *uint32, num uint32, size presenceSize) { + data := findPointerToRaceDetectData(field, num) + if data == nil { + return + } + sp := atomicLoadShadowPresence(&data.shadowPresence) + if sp == nil { + data.raceDetectHookAlloc(size) + sp = atomicLoadShadowPresence(&data.shadowPresence) + } + (*sp)[num] = 1 +} + +// raceDetectHookClearPresent is called by the generated file interface +// (*proto.internalFuncs) ClearPresent to optionally write an unprotected +// shadow bitmap when race detection is enabled. In regular code it is +// a noop. +func raceDetectHookClearPresent(field *uint32, num uint32) { + data := findPointerToRaceDetectData(field, num) + if data == nil { + return + } + sp := atomicLoadShadowPresence(&data.shadowPresence) + if sp != nil { + (*sp)[num] = 0 + } +} diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/impl/checkinit.go b/go-controller/vendor/google.golang.org/protobuf/internal/impl/checkinit.go index f29e6a8fa8..fe2c719ce4 100644 --- a/go-controller/vendor/google.golang.org/protobuf/internal/impl/checkinit.go +++ b/go-controller/vendor/google.golang.org/protobuf/internal/impl/checkinit.go @@ -35,6 +35,12 @@ func (mi *MessageInfo) checkInitializedPointer(p pointer) error { } return nil } + + var presence presence + if mi.presenceOffset.IsValid() { + presence = p.Apply(mi.presenceOffset).PresenceInfo() + } + if mi.extensionOffset.IsValid() { e := p.Apply(mi.extensionOffset).Extensions() if err := mi.isInitExtensions(e); err != nil { @@ -45,6 +51,33 @@ func (mi *MessageInfo) checkInitializedPointer(p pointer) error { if !f.isRequired && f.funcs.isInit == nil { continue } + + if f.presenceIndex != noPresence { + if !presence.Present(f.presenceIndex) { + if f.isRequired { + return errors.RequiredNotSet(string(mi.Desc.Fields().ByNumber(f.num).FullName())) + } + continue + } + if f.funcs.isInit != nil { + f.mi.init() + if f.mi.needsInitCheck { + if f.isLazy && p.Apply(f.offset).AtomicGetPointer().IsNil() { + lazy := *p.Apply(mi.lazyOffset).LazyInfoPtr() + if !lazy.AllowedPartial() { + // Nothing to see here, it was checked on unmarshal + continue + } + mi.lazyUnmarshal(p, f.num) + } + if err := f.funcs.isInit(p.Apply(f.offset), f); err != nil { + return err + } + } + } + continue + } + fptr := p.Apply(f.offset) if f.isPointer && fptr.Elem().IsNil() { if f.isRequired { diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/impl/codec_field.go b/go-controller/vendor/google.golang.org/protobuf/internal/impl/codec_field.go index 7c1f66c8c1..d14d7d93cc 100644 --- a/go-controller/vendor/google.golang.org/protobuf/internal/impl/codec_field.go +++ b/go-controller/vendor/google.golang.org/protobuf/internal/impl/codec_field.go @@ -5,15 +5,12 @@ package impl import ( - "fmt" "reflect" - "sync" "google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/internal/errors" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/reflect/protoregistry" "google.golang.org/protobuf/runtime/protoiface" ) @@ -121,78 +118,6 @@ func (mi *MessageInfo) initOneofFieldCoders(od protoreflect.OneofDescriptor, si } } -func makeWeakMessageFieldCoder(fd protoreflect.FieldDescriptor) pointerCoderFuncs { - var once sync.Once - var messageType protoreflect.MessageType - lazyInit := func() { - once.Do(func() { - messageName := fd.Message().FullName() - messageType, _ = protoregistry.GlobalTypes.FindMessageByName(messageName) - }) - } - - return pointerCoderFuncs{ - size: func(p pointer, f *coderFieldInfo, opts marshalOptions) int { - m, ok := p.WeakFields().get(f.num) - if !ok { - return 0 - } - lazyInit() - if messageType == nil { - panic(fmt.Sprintf("weak message %v is not linked in", fd.Message().FullName())) - } - return sizeMessage(m, f.tagsize, opts) - }, - marshal: func(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) { - m, ok := p.WeakFields().get(f.num) - if !ok { - return b, nil - } - lazyInit() - if messageType == nil { - panic(fmt.Sprintf("weak message %v is not linked in", fd.Message().FullName())) - } - return appendMessage(b, m, f.wiretag, opts) - }, - unmarshal: func(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (unmarshalOutput, error) { - fs := p.WeakFields() - m, ok := fs.get(f.num) - if !ok { - lazyInit() - if messageType == nil { - return unmarshalOutput{}, errUnknown - } - m = messageType.New().Interface() - fs.set(f.num, m) - } - return consumeMessage(b, m, wtyp, opts) - }, - isInit: func(p pointer, f *coderFieldInfo) error { - m, ok := p.WeakFields().get(f.num) - if !ok { - return nil - } - return proto.CheckInitialized(m) - }, - merge: func(dst, src pointer, f *coderFieldInfo, opts mergeOptions) { - sm, ok := src.WeakFields().get(f.num) - if !ok { - return - } - dm, ok := dst.WeakFields().get(f.num) - if !ok { - lazyInit() - if messageType == nil { - panic(fmt.Sprintf("weak message %v is not linked in", fd.Message().FullName())) - } - dm = messageType.New().Interface() - dst.WeakFields().set(f.num, dm) - } - opts.Merge(dm, sm) - }, - } -} - func makeMessageFieldCoder(fd protoreflect.FieldDescriptor, ft reflect.Type) pointerCoderFuncs { if mi := getMessageInfo(ft); mi != nil { funcs := pointerCoderFuncs{ diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/impl/codec_field_opaque.go b/go-controller/vendor/google.golang.org/protobuf/internal/impl/codec_field_opaque.go new file mode 100644 index 0000000000..76818ea252 --- /dev/null +++ b/go-controller/vendor/google.golang.org/protobuf/internal/impl/codec_field_opaque.go @@ -0,0 +1,264 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package impl + +import ( + "fmt" + "reflect" + + "google.golang.org/protobuf/encoding/protowire" + "google.golang.org/protobuf/internal/errors" + "google.golang.org/protobuf/reflect/protoreflect" +) + +func makeOpaqueMessageFieldCoder(fd protoreflect.FieldDescriptor, ft reflect.Type) (*MessageInfo, pointerCoderFuncs) { + mi := getMessageInfo(ft) + if mi == nil { + panic(fmt.Sprintf("invalid field: %v: unsupported message type %v", fd.FullName(), ft)) + } + switch fd.Kind() { + case protoreflect.MessageKind: + return mi, pointerCoderFuncs{ + size: sizeOpaqueMessage, + marshal: appendOpaqueMessage, + unmarshal: consumeOpaqueMessage, + isInit: isInitOpaqueMessage, + merge: mergeOpaqueMessage, + } + case protoreflect.GroupKind: + return mi, pointerCoderFuncs{ + size: sizeOpaqueGroup, + marshal: appendOpaqueGroup, + unmarshal: consumeOpaqueGroup, + isInit: isInitOpaqueMessage, + merge: mergeOpaqueMessage, + } + } + panic("unexpected field kind") +} + +func sizeOpaqueMessage(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) { + return protowire.SizeBytes(f.mi.sizePointer(p.AtomicGetPointer(), opts)) + f.tagsize +} + +func appendOpaqueMessage(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) { + mp := p.AtomicGetPointer() + calculatedSize := f.mi.sizePointer(mp, opts) + b = protowire.AppendVarint(b, f.wiretag) + b = protowire.AppendVarint(b, uint64(calculatedSize)) + before := len(b) + b, err := f.mi.marshalAppendPointer(b, mp, opts) + if measuredSize := len(b) - before; calculatedSize != measuredSize && err == nil { + return nil, errors.MismatchedSizeCalculation(calculatedSize, measuredSize) + } + return b, err +} + +func consumeOpaqueMessage(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) { + if wtyp != protowire.BytesType { + return out, errUnknown + } + v, n := protowire.ConsumeBytes(b) + if n < 0 { + return out, errDecode + } + mp := p.AtomicGetPointer() + if mp.IsNil() { + mp = p.AtomicSetPointerIfNil(pointerOfValue(reflect.New(f.mi.GoReflectType.Elem()))) + } + o, err := f.mi.unmarshalPointer(v, mp, 0, opts) + if err != nil { + return out, err + } + out.n = n + out.initialized = o.initialized + return out, nil +} + +func isInitOpaqueMessage(p pointer, f *coderFieldInfo) error { + mp := p.AtomicGetPointer() + if mp.IsNil() { + return nil + } + return f.mi.checkInitializedPointer(mp) +} + +func mergeOpaqueMessage(dst, src pointer, f *coderFieldInfo, opts mergeOptions) { + dstmp := dst.AtomicGetPointer() + if dstmp.IsNil() { + dstmp = dst.AtomicSetPointerIfNil(pointerOfValue(reflect.New(f.mi.GoReflectType.Elem()))) + } + f.mi.mergePointer(dstmp, src.AtomicGetPointer(), opts) +} + +func sizeOpaqueGroup(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) { + return 2*f.tagsize + f.mi.sizePointer(p.AtomicGetPointer(), opts) +} + +func appendOpaqueGroup(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) { + b = protowire.AppendVarint(b, f.wiretag) // start group + b, err := f.mi.marshalAppendPointer(b, p.AtomicGetPointer(), opts) + b = protowire.AppendVarint(b, f.wiretag+1) // end group + return b, err +} + +func consumeOpaqueGroup(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) { + if wtyp != protowire.StartGroupType { + return out, errUnknown + } + mp := p.AtomicGetPointer() + if mp.IsNil() { + mp = p.AtomicSetPointerIfNil(pointerOfValue(reflect.New(f.mi.GoReflectType.Elem()))) + } + o, e := f.mi.unmarshalPointer(b, mp, f.num, opts) + return o, e +} + +func makeOpaqueRepeatedMessageFieldCoder(fd protoreflect.FieldDescriptor, ft reflect.Type) (*MessageInfo, pointerCoderFuncs) { + if ft.Kind() != reflect.Ptr || ft.Elem().Kind() != reflect.Slice { + panic(fmt.Sprintf("invalid field: %v: unsupported type for opaque repeated message: %v", fd.FullName(), ft)) + } + mt := ft.Elem().Elem() // *[]*T -> *T + mi := getMessageInfo(mt) + if mi == nil { + panic(fmt.Sprintf("invalid field: %v: unsupported message type %v", fd.FullName(), mt)) + } + switch fd.Kind() { + case protoreflect.MessageKind: + return mi, pointerCoderFuncs{ + size: sizeOpaqueMessageSlice, + marshal: appendOpaqueMessageSlice, + unmarshal: consumeOpaqueMessageSlice, + isInit: isInitOpaqueMessageSlice, + merge: mergeOpaqueMessageSlice, + } + case protoreflect.GroupKind: + return mi, pointerCoderFuncs{ + size: sizeOpaqueGroupSlice, + marshal: appendOpaqueGroupSlice, + unmarshal: consumeOpaqueGroupSlice, + isInit: isInitOpaqueMessageSlice, + merge: mergeOpaqueMessageSlice, + } + } + panic("unexpected field kind") +} + +func sizeOpaqueMessageSlice(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) { + s := p.AtomicGetPointer().PointerSlice() + n := 0 + for _, v := range s { + n += protowire.SizeBytes(f.mi.sizePointer(v, opts)) + f.tagsize + } + return n +} + +func appendOpaqueMessageSlice(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) { + s := p.AtomicGetPointer().PointerSlice() + var err error + for _, v := range s { + b = protowire.AppendVarint(b, f.wiretag) + siz := f.mi.sizePointer(v, opts) + b = protowire.AppendVarint(b, uint64(siz)) + before := len(b) + b, err = f.mi.marshalAppendPointer(b, v, opts) + if err != nil { + return b, err + } + if measuredSize := len(b) - before; siz != measuredSize { + return nil, errors.MismatchedSizeCalculation(siz, measuredSize) + } + } + return b, nil +} + +func consumeOpaqueMessageSlice(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) { + if wtyp != protowire.BytesType { + return out, errUnknown + } + v, n := protowire.ConsumeBytes(b) + if n < 0 { + return out, errDecode + } + mp := pointerOfValue(reflect.New(f.mi.GoReflectType.Elem())) + o, err := f.mi.unmarshalPointer(v, mp, 0, opts) + if err != nil { + return out, err + } + sp := p.AtomicGetPointer() + if sp.IsNil() { + sp = p.AtomicSetPointerIfNil(pointerOfValue(reflect.New(f.ft.Elem()))) + } + sp.AppendPointerSlice(mp) + out.n = n + out.initialized = o.initialized + return out, nil +} + +func isInitOpaqueMessageSlice(p pointer, f *coderFieldInfo) error { + sp := p.AtomicGetPointer() + if sp.IsNil() { + return nil + } + s := sp.PointerSlice() + for _, v := range s { + if err := f.mi.checkInitializedPointer(v); err != nil { + return err + } + } + return nil +} + +func mergeOpaqueMessageSlice(dst, src pointer, f *coderFieldInfo, opts mergeOptions) { + ds := dst.AtomicGetPointer() + if ds.IsNil() { + ds = dst.AtomicSetPointerIfNil(pointerOfValue(reflect.New(f.ft.Elem()))) + } + for _, sp := range src.AtomicGetPointer().PointerSlice() { + dm := pointerOfValue(reflect.New(f.mi.GoReflectType.Elem())) + f.mi.mergePointer(dm, sp, opts) + ds.AppendPointerSlice(dm) + } +} + +func sizeOpaqueGroupSlice(p pointer, f *coderFieldInfo, opts marshalOptions) (size int) { + s := p.AtomicGetPointer().PointerSlice() + n := 0 + for _, v := range s { + n += 2*f.tagsize + f.mi.sizePointer(v, opts) + } + return n +} + +func appendOpaqueGroupSlice(b []byte, p pointer, f *coderFieldInfo, opts marshalOptions) ([]byte, error) { + s := p.AtomicGetPointer().PointerSlice() + var err error + for _, v := range s { + b = protowire.AppendVarint(b, f.wiretag) // start group + b, err = f.mi.marshalAppendPointer(b, v, opts) + if err != nil { + return b, err + } + b = protowire.AppendVarint(b, f.wiretag+1) // end group + } + return b, nil +} + +func consumeOpaqueGroupSlice(b []byte, p pointer, wtyp protowire.Type, f *coderFieldInfo, opts unmarshalOptions) (out unmarshalOutput, err error) { + if wtyp != protowire.StartGroupType { + return out, errUnknown + } + mp := pointerOfValue(reflect.New(f.mi.GoReflectType.Elem())) + out, err = f.mi.unmarshalPointer(b, mp, f.num, opts) + if err != nil { + return out, err + } + sp := p.AtomicGetPointer() + if sp.IsNil() { + sp = p.AtomicSetPointerIfNil(pointerOfValue(reflect.New(f.ft.Elem()))) + } + sp.AppendPointerSlice(mp) + return out, err +} diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/impl/codec_map.go b/go-controller/vendor/google.golang.org/protobuf/internal/impl/codec_map.go index fb35f0bae9..229c698013 100644 --- a/go-controller/vendor/google.golang.org/protobuf/internal/impl/codec_map.go +++ b/go-controller/vendor/google.golang.org/protobuf/internal/impl/codec_map.go @@ -94,7 +94,7 @@ func sizeMap(mapv reflect.Value, mapi *mapInfo, f *coderFieldInfo, opts marshalO return 0 } n := 0 - iter := mapRange(mapv) + iter := mapv.MapRange() for iter.Next() { key := mapi.conv.keyConv.PBValueOf(iter.Key()).MapKey() keySize := mapi.keyFuncs.size(key.Value(), mapKeyTagSize, opts) @@ -281,7 +281,7 @@ func appendMap(b []byte, mapv reflect.Value, mapi *mapInfo, f *coderFieldInfo, o if opts.Deterministic() { return appendMapDeterministic(b, mapv, mapi, f, opts) } - iter := mapRange(mapv) + iter := mapv.MapRange() for iter.Next() { var err error b = protowire.AppendVarint(b, f.wiretag) @@ -328,7 +328,7 @@ func isInitMap(mapv reflect.Value, mapi *mapInfo, f *coderFieldInfo) error { if !mi.needsInitCheck { return nil } - iter := mapRange(mapv) + iter := mapv.MapRange() for iter.Next() { val := pointerOfValue(iter.Value()) if err := mi.checkInitializedPointer(val); err != nil { @@ -336,7 +336,7 @@ func isInitMap(mapv reflect.Value, mapi *mapInfo, f *coderFieldInfo) error { } } } else { - iter := mapRange(mapv) + iter := mapv.MapRange() for iter.Next() { val := mapi.conv.valConv.PBValueOf(iter.Value()) if err := mapi.valFuncs.isInit(val); err != nil { @@ -356,7 +356,7 @@ func mergeMap(dst, src pointer, f *coderFieldInfo, opts mergeOptions) { if dstm.IsNil() { dstm.Set(reflect.MakeMap(f.ft)) } - iter := mapRange(srcm) + iter := srcm.MapRange() for iter.Next() { dstm.SetMapIndex(iter.Key(), iter.Value()) } @@ -371,7 +371,7 @@ func mergeMapOfBytes(dst, src pointer, f *coderFieldInfo, opts mergeOptions) { if dstm.IsNil() { dstm.Set(reflect.MakeMap(f.ft)) } - iter := mapRange(srcm) + iter := srcm.MapRange() for iter.Next() { dstm.SetMapIndex(iter.Key(), reflect.ValueOf(append(emptyBuf[:], iter.Value().Bytes()...))) } @@ -386,7 +386,7 @@ func mergeMapOfMessage(dst, src pointer, f *coderFieldInfo, opts mergeOptions) { if dstm.IsNil() { dstm.Set(reflect.MakeMap(f.ft)) } - iter := mapRange(srcm) + iter := srcm.MapRange() for iter.Next() { val := reflect.New(f.ft.Elem().Elem()) if f.mi != nil { diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/impl/codec_map_go111.go b/go-controller/vendor/google.golang.org/protobuf/internal/impl/codec_map_go111.go deleted file mode 100644 index 4b15493f2f..0000000000 --- a/go-controller/vendor/google.golang.org/protobuf/internal/impl/codec_map_go111.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !go1.12 -// +build !go1.12 - -package impl - -import "reflect" - -type mapIter struct { - v reflect.Value - keys []reflect.Value -} - -// mapRange provides a less-efficient equivalent to -// the Go 1.12 reflect.Value.MapRange method. -func mapRange(v reflect.Value) *mapIter { - return &mapIter{v: v} -} - -func (i *mapIter) Next() bool { - if i.keys == nil { - i.keys = i.v.MapKeys() - } else { - i.keys = i.keys[1:] - } - return len(i.keys) > 0 -} - -func (i *mapIter) Key() reflect.Value { - return i.keys[0] -} - -func (i *mapIter) Value() reflect.Value { - return i.v.MapIndex(i.keys[0]) -} diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/impl/codec_map_go112.go b/go-controller/vendor/google.golang.org/protobuf/internal/impl/codec_map_go112.go deleted file mode 100644 index 0b31b66eaf..0000000000 --- a/go-controller/vendor/google.golang.org/protobuf/internal/impl/codec_map_go112.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build go1.12 -// +build go1.12 - -package impl - -import "reflect" - -func mapRange(v reflect.Value) *reflect.MapIter { return v.MapRange() } diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/impl/codec_message.go b/go-controller/vendor/google.golang.org/protobuf/internal/impl/codec_message.go index 78be9df342..f78b57b046 100644 --- a/go-controller/vendor/google.golang.org/protobuf/internal/impl/codec_message.go +++ b/go-controller/vendor/google.golang.org/protobuf/internal/impl/codec_message.go @@ -32,6 +32,10 @@ type coderMessageInfo struct { needsInitCheck bool isMessageSet bool numRequiredFields uint8 + + lazyOffset offset + presenceOffset offset + presenceSize presenceSize } type coderFieldInfo struct { @@ -45,12 +49,19 @@ type coderFieldInfo struct { tagsize int // size of the varint-encoded tag isPointer bool // true if IsNil may be called on the struct field isRequired bool // true if field is required + + isLazy bool + presenceIndex uint32 } +const noPresence = 0xffffffff + func (mi *MessageInfo) makeCoderMethods(t reflect.Type, si structInfo) { mi.sizecacheOffset = invalidOffset mi.unknownOffset = invalidOffset mi.extensionOffset = invalidOffset + mi.lazyOffset = invalidOffset + mi.presenceOffset = si.presenceOffset if si.sizecacheOffset.IsValid() && si.sizecacheType == sizecacheType { mi.sizecacheOffset = si.sizecacheOffset @@ -107,12 +118,9 @@ func (mi *MessageInfo) makeCoderMethods(t reflect.Type, si structInfo) { }, } case isOneof: - fieldOffset = offsetOf(fs, mi.Exporter) - case fd.IsWeak(): - fieldOffset = si.weakOffset - funcs = makeWeakMessageFieldCoder(fd) + fieldOffset = offsetOf(fs) default: - fieldOffset = offsetOf(fs, mi.Exporter) + fieldOffset = offsetOf(fs) childMessage, funcs = fieldCoder(fd, ft) } cf := &preallocFields[i] @@ -127,6 +135,8 @@ func (mi *MessageInfo) makeCoderMethods(t reflect.Type, si structInfo) { validation: newFieldValidationInfo(mi, si, fd, ft), isPointer: fd.Cardinality() == protoreflect.Repeated || fd.HasPresence(), isRequired: fd.Cardinality() == protoreflect.Required, + + presenceIndex: noPresence, } mi.orderedCoderFields = append(mi.orderedCoderFields, cf) mi.coderFields[cf.num] = cf diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/impl/codec_message_opaque.go b/go-controller/vendor/google.golang.org/protobuf/internal/impl/codec_message_opaque.go new file mode 100644 index 0000000000..41c1f74ef8 --- /dev/null +++ b/go-controller/vendor/google.golang.org/protobuf/internal/impl/codec_message_opaque.go @@ -0,0 +1,153 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package impl + +import ( + "fmt" + "reflect" + "sort" + + "google.golang.org/protobuf/encoding/protowire" + "google.golang.org/protobuf/internal/encoding/messageset" + "google.golang.org/protobuf/internal/order" + "google.golang.org/protobuf/reflect/protoreflect" + piface "google.golang.org/protobuf/runtime/protoiface" +) + +func (mi *MessageInfo) makeOpaqueCoderMethods(t reflect.Type, si opaqueStructInfo) { + mi.sizecacheOffset = si.sizecacheOffset + mi.unknownOffset = si.unknownOffset + mi.unknownPtrKind = si.unknownType.Kind() == reflect.Ptr + mi.extensionOffset = si.extensionOffset + mi.lazyOffset = si.lazyOffset + mi.presenceOffset = si.presenceOffset + + mi.coderFields = make(map[protowire.Number]*coderFieldInfo) + fields := mi.Desc.Fields() + for i := 0; i < fields.Len(); i++ { + fd := fields.Get(i) + + fs := si.fieldsByNumber[fd.Number()] + if fd.ContainingOneof() != nil && !fd.ContainingOneof().IsSynthetic() { + fs = si.oneofsByName[fd.ContainingOneof().Name()] + } + ft := fs.Type + var wiretag uint64 + if !fd.IsPacked() { + wiretag = protowire.EncodeTag(fd.Number(), wireTypes[fd.Kind()]) + } else { + wiretag = protowire.EncodeTag(fd.Number(), protowire.BytesType) + } + var fieldOffset offset + var funcs pointerCoderFuncs + var childMessage *MessageInfo + switch { + case fd.ContainingOneof() != nil && !fd.ContainingOneof().IsSynthetic(): + fieldOffset = offsetOf(fs) + case fd.Message() != nil && !fd.IsMap(): + fieldOffset = offsetOf(fs) + if fd.IsList() { + childMessage, funcs = makeOpaqueRepeatedMessageFieldCoder(fd, ft) + } else { + childMessage, funcs = makeOpaqueMessageFieldCoder(fd, ft) + } + default: + fieldOffset = offsetOf(fs) + childMessage, funcs = fieldCoder(fd, ft) + } + cf := &coderFieldInfo{ + num: fd.Number(), + offset: fieldOffset, + wiretag: wiretag, + ft: ft, + tagsize: protowire.SizeVarint(wiretag), + funcs: funcs, + mi: childMessage, + validation: newFieldValidationInfo(mi, si.structInfo, fd, ft), + isPointer: (fd.Cardinality() == protoreflect.Repeated || + fd.Kind() == protoreflect.MessageKind || + fd.Kind() == protoreflect.GroupKind), + isRequired: fd.Cardinality() == protoreflect.Required, + presenceIndex: noPresence, + } + + // TODO: Use presence for all fields. + // + // In some cases, such as maps, presence means only "might be set" rather + // than "is definitely set", but every field should have a presence bit to + // permit us to skip over definitely-unset fields at marshal time. + + var hasPresence bool + hasPresence, cf.isLazy = usePresenceForField(si, fd) + + if hasPresence { + cf.presenceIndex, mi.presenceSize = presenceIndex(mi.Desc, fd) + } + + mi.orderedCoderFields = append(mi.orderedCoderFields, cf) + mi.coderFields[cf.num] = cf + } + for i, oneofs := 0, mi.Desc.Oneofs(); i < oneofs.Len(); i++ { + if od := oneofs.Get(i); !od.IsSynthetic() { + mi.initOneofFieldCoders(od, si.structInfo) + } + } + if messageset.IsMessageSet(mi.Desc) { + if !mi.extensionOffset.IsValid() { + panic(fmt.Sprintf("%v: MessageSet with no extensions field", mi.Desc.FullName())) + } + if !mi.unknownOffset.IsValid() { + panic(fmt.Sprintf("%v: MessageSet with no unknown field", mi.Desc.FullName())) + } + mi.isMessageSet = true + } + sort.Slice(mi.orderedCoderFields, func(i, j int) bool { + return mi.orderedCoderFields[i].num < mi.orderedCoderFields[j].num + }) + + var maxDense protoreflect.FieldNumber + for _, cf := range mi.orderedCoderFields { + if cf.num >= 16 && cf.num >= 2*maxDense { + break + } + maxDense = cf.num + } + mi.denseCoderFields = make([]*coderFieldInfo, maxDense+1) + for _, cf := range mi.orderedCoderFields { + if int(cf.num) > len(mi.denseCoderFields) { + break + } + mi.denseCoderFields[cf.num] = cf + } + + // To preserve compatibility with historic wire output, marshal oneofs last. + if mi.Desc.Oneofs().Len() > 0 { + sort.Slice(mi.orderedCoderFields, func(i, j int) bool { + fi := fields.ByNumber(mi.orderedCoderFields[i].num) + fj := fields.ByNumber(mi.orderedCoderFields[j].num) + return order.LegacyFieldOrder(fi, fj) + }) + } + + mi.needsInitCheck = needsInitCheck(mi.Desc) + if mi.methods.Marshal == nil && mi.methods.Size == nil { + mi.methods.Flags |= piface.SupportMarshalDeterministic + mi.methods.Marshal = mi.marshal + mi.methods.Size = mi.size + } + if mi.methods.Unmarshal == nil { + mi.methods.Flags |= piface.SupportUnmarshalDiscardUnknown + mi.methods.Unmarshal = mi.unmarshal + } + if mi.methods.CheckInitialized == nil { + mi.methods.CheckInitialized = mi.checkInitialized + } + if mi.methods.Merge == nil { + mi.methods.Merge = mi.merge + } + if mi.methods.Equal == nil { + mi.methods.Equal = equal + } +} diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/impl/convert_map.go b/go-controller/vendor/google.golang.org/protobuf/internal/impl/convert_map.go index 304244a651..e4580b3ac2 100644 --- a/go-controller/vendor/google.golang.org/protobuf/internal/impl/convert_map.go +++ b/go-controller/vendor/google.golang.org/protobuf/internal/impl/convert_map.go @@ -101,7 +101,7 @@ func (ms *mapReflect) Mutable(k protoreflect.MapKey) protoreflect.Value { return v } func (ms *mapReflect) Range(f func(protoreflect.MapKey, protoreflect.Value) bool) { - iter := mapRange(ms.v) + iter := ms.v.MapRange() for iter.Next() { k := ms.keyConv.PBValueOf(iter.Key()).MapKey() v := ms.valConv.PBValueOf(iter.Value()) diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/impl/decode.go b/go-controller/vendor/google.golang.org/protobuf/internal/impl/decode.go index cda0520c27..e0dd21fa5f 100644 --- a/go-controller/vendor/google.golang.org/protobuf/internal/impl/decode.go +++ b/go-controller/vendor/google.golang.org/protobuf/internal/impl/decode.go @@ -34,6 +34,8 @@ func (o unmarshalOptions) Options() proto.UnmarshalOptions { AllowPartial: true, DiscardUnknown: o.DiscardUnknown(), Resolver: o.resolver, + + NoLazyDecoding: o.NoLazyDecoding(), } } @@ -41,13 +43,26 @@ func (o unmarshalOptions) DiscardUnknown() bool { return o.flags&protoiface.UnmarshalDiscardUnknown != 0 } -func (o unmarshalOptions) IsDefault() bool { - return o.flags == 0 && o.resolver == protoregistry.GlobalTypes +func (o unmarshalOptions) AliasBuffer() bool { return o.flags&protoiface.UnmarshalAliasBuffer != 0 } +func (o unmarshalOptions) Validated() bool { return o.flags&protoiface.UnmarshalValidated != 0 } +func (o unmarshalOptions) NoLazyDecoding() bool { + return o.flags&protoiface.UnmarshalNoLazyDecoding != 0 +} + +func (o unmarshalOptions) CanBeLazy() bool { + if o.resolver != protoregistry.GlobalTypes { + return false + } + // We ignore the UnmarshalInvalidateSizeCache even though it's not in the default set + return (o.flags & ^(protoiface.UnmarshalAliasBuffer | protoiface.UnmarshalValidated | protoiface.UnmarshalCheckRequired)) == 0 } var lazyUnmarshalOptions = unmarshalOptions{ resolver: protoregistry.GlobalTypes, - depth: protowire.DefaultRecursionLimit, + + flags: protoiface.UnmarshalAliasBuffer | protoiface.UnmarshalValidated, + + depth: protowire.DefaultRecursionLimit, } type unmarshalOutput struct { @@ -94,9 +109,30 @@ func (mi *MessageInfo) unmarshalPointer(b []byte, p pointer, groupTag protowire. if flags.ProtoLegacy && mi.isMessageSet { return unmarshalMessageSet(mi, b, p, opts) } + + lazyDecoding := LazyEnabled() // default + if opts.NoLazyDecoding() { + lazyDecoding = false // explicitly disabled + } + if mi.lazyOffset.IsValid() && lazyDecoding { + return mi.unmarshalPointerLazy(b, p, groupTag, opts) + } + return mi.unmarshalPointerEager(b, p, groupTag, opts) +} + +// unmarshalPointerEager is the message unmarshalling function for all messages that are not lazy. +// The corresponding function for Lazy is in google_lazy.go. +func (mi *MessageInfo) unmarshalPointerEager(b []byte, p pointer, groupTag protowire.Number, opts unmarshalOptions) (out unmarshalOutput, err error) { + initialized := true var requiredMask uint64 var exts *map[int32]ExtensionField + + var presence presence + if mi.presenceOffset.IsValid() { + presence = p.Apply(mi.presenceOffset).PresenceInfo() + } + start := len(b) for len(b) > 0 { // Parse the tag (field number and wire type). @@ -154,6 +190,11 @@ func (mi *MessageInfo) unmarshalPointer(b []byte, p pointer, groupTag protowire. if f.funcs.isInit != nil && !o.initialized { initialized = false } + + if f.presenceIndex != noPresence { + presence.SetPresentUnatomic(f.presenceIndex, mi.presenceSize) + } + default: // Possible extension. if exts == nil && mi.extensionOffset.IsValid() { @@ -222,7 +263,7 @@ func (mi *MessageInfo) unmarshalExtension(b []byte, num protowire.Number, wtyp p return out, errUnknown } if flags.LazyUnmarshalExtensions { - if opts.IsDefault() && x.canLazy(xt) { + if opts.CanBeLazy() && x.canLazy(xt) { out, valid := skipExtension(b, xi, num, wtyp, opts) switch valid { case ValidationValid: @@ -270,6 +311,13 @@ func skipExtension(b []byte, xi *extensionFieldInfo, num protowire.Number, wtyp if n < 0 { return out, ValidationUnknown } + + if opts.Validated() { + out.initialized = true + out.n = n + return out, ValidationValid + } + out, st := xi.validation.mi.validate(v, 0, opts) out.n = n return out, st diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/impl/encode.go b/go-controller/vendor/google.golang.org/protobuf/internal/impl/encode.go index 6254f5de41..b2e212291d 100644 --- a/go-controller/vendor/google.golang.org/protobuf/internal/impl/encode.go +++ b/go-controller/vendor/google.golang.org/protobuf/internal/impl/encode.go @@ -10,6 +10,7 @@ import ( "sync/atomic" "google.golang.org/protobuf/internal/flags" + "google.golang.org/protobuf/internal/protolazy" "google.golang.org/protobuf/proto" piface "google.golang.org/protobuf/runtime/protoiface" ) @@ -71,11 +72,39 @@ func (mi *MessageInfo) sizePointerSlow(p pointer, opts marshalOptions) (size int e := p.Apply(mi.extensionOffset).Extensions() size += mi.sizeExtensions(e, opts) } + + var lazy **protolazy.XXX_lazyUnmarshalInfo + var presence presence + if mi.presenceOffset.IsValid() { + presence = p.Apply(mi.presenceOffset).PresenceInfo() + if mi.lazyOffset.IsValid() { + lazy = p.Apply(mi.lazyOffset).LazyInfoPtr() + } + } + for _, f := range mi.orderedCoderFields { if f.funcs.size == nil { continue } fptr := p.Apply(f.offset) + + if f.presenceIndex != noPresence { + if !presence.Present(f.presenceIndex) { + continue + } + + if f.isLazy && fptr.AtomicGetPointer().IsNil() { + if lazyFields(opts) { + size += (*lazy).SizeField(uint32(f.num)) + continue + } else { + mi.lazyUnmarshal(p, f.num) + } + } + size += f.funcs.size(fptr, f, opts) + continue + } + if f.isPointer && fptr.Elem().IsNil() { continue } @@ -134,11 +163,52 @@ func (mi *MessageInfo) marshalAppendPointer(b []byte, p pointer, opts marshalOpt return b, err } } + + var lazy **protolazy.XXX_lazyUnmarshalInfo + var presence presence + if mi.presenceOffset.IsValid() { + presence = p.Apply(mi.presenceOffset).PresenceInfo() + if mi.lazyOffset.IsValid() { + lazy = p.Apply(mi.lazyOffset).LazyInfoPtr() + } + } + for _, f := range mi.orderedCoderFields { if f.funcs.marshal == nil { continue } fptr := p.Apply(f.offset) + + if f.presenceIndex != noPresence { + if !presence.Present(f.presenceIndex) { + continue + } + if f.isLazy { + // Be careful, this field needs to be read atomically, like for a get + if f.isPointer && fptr.AtomicGetPointer().IsNil() { + if lazyFields(opts) { + b, _ = (*lazy).AppendField(b, uint32(f.num)) + continue + } else { + mi.lazyUnmarshal(p, f.num) + } + } + + b, err = f.funcs.marshal(b, fptr, f, opts) + if err != nil { + return b, err + } + continue + } else if f.isPointer && fptr.Elem().IsNil() { + continue + } + b, err = f.funcs.marshal(b, fptr, f, opts) + if err != nil { + return b, err + } + continue + } + if f.isPointer && fptr.Elem().IsNil() { continue } @@ -163,6 +233,14 @@ func fullyLazyExtensions(opts marshalOptions) bool { return opts.flags&piface.MarshalDeterministic == 0 } +// lazyFields returns true if we should attempt to keep fields lazy over size and marshal. +func lazyFields(opts marshalOptions) bool { + // When deterministic marshaling is requested, force an unmarshal for lazy + // fields to produce a deterministic result, instead of passing through + // bytes lazily that may or may not match what Go Protobuf would produce. + return opts.flags&piface.MarshalDeterministic == 0 +} + func (mi *MessageInfo) sizeExtensions(ext *map[int32]ExtensionField, opts marshalOptions) (n int) { if ext == nil { return 0 diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/impl/lazy.go b/go-controller/vendor/google.golang.org/protobuf/internal/impl/lazy.go new file mode 100644 index 0000000000..c7de31e243 --- /dev/null +++ b/go-controller/vendor/google.golang.org/protobuf/internal/impl/lazy.go @@ -0,0 +1,433 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package impl + +import ( + "fmt" + "math/bits" + "os" + "reflect" + "sort" + "sync/atomic" + + "google.golang.org/protobuf/encoding/protowire" + "google.golang.org/protobuf/internal/errors" + "google.golang.org/protobuf/internal/protolazy" + "google.golang.org/protobuf/reflect/protoreflect" + preg "google.golang.org/protobuf/reflect/protoregistry" + piface "google.golang.org/protobuf/runtime/protoiface" +) + +var enableLazy int32 = func() int32 { + if os.Getenv("GOPROTODEBUG") == "nolazy" { + return 0 + } + return 1 +}() + +// EnableLazyUnmarshal enables lazy unmarshaling. +func EnableLazyUnmarshal(enable bool) { + if enable { + atomic.StoreInt32(&enableLazy, 1) + return + } + atomic.StoreInt32(&enableLazy, 0) +} + +// LazyEnabled reports whether lazy unmarshalling is currently enabled. +func LazyEnabled() bool { + return atomic.LoadInt32(&enableLazy) != 0 +} + +// UnmarshalField unmarshals a field in a message. +func UnmarshalField(m interface{}, num protowire.Number) { + switch m := m.(type) { + case *messageState: + m.messageInfo().lazyUnmarshal(m.pointer(), num) + case *messageReflectWrapper: + m.messageInfo().lazyUnmarshal(m.pointer(), num) + default: + panic(fmt.Sprintf("unsupported wrapper type %T", m)) + } +} + +func (mi *MessageInfo) lazyUnmarshal(p pointer, num protoreflect.FieldNumber) { + var f *coderFieldInfo + if int(num) < len(mi.denseCoderFields) { + f = mi.denseCoderFields[num] + } else { + f = mi.coderFields[num] + } + if f == nil { + panic(fmt.Sprintf("lazyUnmarshal: field info for %v.%v", mi.Desc.FullName(), num)) + } + lazy := *p.Apply(mi.lazyOffset).LazyInfoPtr() + start, end, found, _, multipleEntries := lazy.FindFieldInProto(uint32(num)) + if !found && multipleEntries == nil { + panic(fmt.Sprintf("lazyUnmarshal: can't find field data for %v.%v", mi.Desc.FullName(), num)) + } + // The actual pointer in the message can not be set until the whole struct is filled in, otherwise we will have races. + // Create another pointer and set it atomically, if we won the race and the pointer in the original message is still nil. + fp := pointerOfValue(reflect.New(f.ft)) + if multipleEntries != nil { + for _, entry := range multipleEntries { + mi.unmarshalField(lazy.Buffer()[entry.Start:entry.End], fp, f, lazy, lazy.UnmarshalFlags()) + } + } else { + mi.unmarshalField(lazy.Buffer()[start:end], fp, f, lazy, lazy.UnmarshalFlags()) + } + p.Apply(f.offset).AtomicSetPointerIfNil(fp.Elem()) +} + +func (mi *MessageInfo) unmarshalField(b []byte, p pointer, f *coderFieldInfo, lazyInfo *protolazy.XXX_lazyUnmarshalInfo, flags piface.UnmarshalInputFlags) error { + opts := lazyUnmarshalOptions + opts.flags |= flags + for len(b) > 0 { + // Parse the tag (field number and wire type). + var tag uint64 + if b[0] < 0x80 { + tag = uint64(b[0]) + b = b[1:] + } else if len(b) >= 2 && b[1] < 128 { + tag = uint64(b[0]&0x7f) + uint64(b[1])<<7 + b = b[2:] + } else { + var n int + tag, n = protowire.ConsumeVarint(b) + if n < 0 { + return errors.New("invalid wire data") + } + b = b[n:] + } + var num protowire.Number + if n := tag >> 3; n < uint64(protowire.MinValidNumber) || n > uint64(protowire.MaxValidNumber) { + return errors.New("invalid wire data") + } else { + num = protowire.Number(n) + } + wtyp := protowire.Type(tag & 7) + if num == f.num { + o, err := f.funcs.unmarshal(b, p, wtyp, f, opts) + if err == nil { + b = b[o.n:] + continue + } + if err != errUnknown { + return err + } + } + n := protowire.ConsumeFieldValue(num, wtyp, b) + if n < 0 { + return errors.New("invalid wire data") + } + b = b[n:] + } + return nil +} + +func (mi *MessageInfo) skipField(b []byte, f *coderFieldInfo, wtyp protowire.Type, opts unmarshalOptions) (out unmarshalOutput, _ ValidationStatus) { + fmi := f.validation.mi + if fmi == nil { + fd := mi.Desc.Fields().ByNumber(f.num) + if fd == nil { + return out, ValidationUnknown + } + messageName := fd.Message().FullName() + messageType, err := preg.GlobalTypes.FindMessageByName(messageName) + if err != nil { + return out, ValidationUnknown + } + var ok bool + fmi, ok = messageType.(*MessageInfo) + if !ok { + return out, ValidationUnknown + } + } + fmi.init() + switch f.validation.typ { + case validationTypeMessage: + if wtyp != protowire.BytesType { + return out, ValidationWrongWireType + } + v, n := protowire.ConsumeBytes(b) + if n < 0 { + return out, ValidationInvalid + } + out, st := fmi.validate(v, 0, opts) + out.n = n + return out, st + case validationTypeGroup: + if wtyp != protowire.StartGroupType { + return out, ValidationWrongWireType + } + out, st := fmi.validate(b, f.num, opts) + return out, st + default: + return out, ValidationUnknown + } +} + +// unmarshalPointerLazy is similar to unmarshalPointerEager, but it +// specifically handles lazy unmarshalling. it expects lazyOffset and +// presenceOffset to both be valid. +func (mi *MessageInfo) unmarshalPointerLazy(b []byte, p pointer, groupTag protowire.Number, opts unmarshalOptions) (out unmarshalOutput, err error) { + initialized := true + var requiredMask uint64 + var lazy **protolazy.XXX_lazyUnmarshalInfo + var presence presence + var lazyIndex []protolazy.IndexEntry + var lastNum protowire.Number + outOfOrder := false + lazyDecode := false + presence = p.Apply(mi.presenceOffset).PresenceInfo() + lazy = p.Apply(mi.lazyOffset).LazyInfoPtr() + if !presence.AnyPresent(mi.presenceSize) { + if opts.CanBeLazy() { + // If the message contains existing data, we need to merge into it. + // Lazy unmarshaling doesn't merge, so only enable it when the + // message is empty (has no presence bitmap). + lazyDecode = true + if *lazy == nil { + *lazy = &protolazy.XXX_lazyUnmarshalInfo{} + } + (*lazy).SetUnmarshalFlags(opts.flags) + if !opts.AliasBuffer() { + // Make a copy of the buffer for lazy unmarshaling. + // Set the AliasBuffer flag so recursive unmarshal + // operations reuse the copy. + b = append([]byte{}, b...) + opts.flags |= piface.UnmarshalAliasBuffer + } + (*lazy).SetBuffer(b) + } + } + // Track special handling of lazy fields. + // + // In the common case, all fields are lazyValidateOnly (and lazyFields remains nil). + // In the event that validation for a field fails, this map tracks handling of the field. + type lazyAction uint8 + const ( + lazyValidateOnly lazyAction = iota // validate the field only + lazyUnmarshalNow // eagerly unmarshal the field + lazyUnmarshalLater // unmarshal the field after the message is fully processed + ) + var lazyFields map[*coderFieldInfo]lazyAction + var exts *map[int32]ExtensionField + start := len(b) + pos := 0 + for len(b) > 0 { + // Parse the tag (field number and wire type). + var tag uint64 + if b[0] < 0x80 { + tag = uint64(b[0]) + b = b[1:] + } else if len(b) >= 2 && b[1] < 128 { + tag = uint64(b[0]&0x7f) + uint64(b[1])<<7 + b = b[2:] + } else { + var n int + tag, n = protowire.ConsumeVarint(b) + if n < 0 { + return out, errDecode + } + b = b[n:] + } + var num protowire.Number + if n := tag >> 3; n < uint64(protowire.MinValidNumber) || n > uint64(protowire.MaxValidNumber) { + return out, errors.New("invalid field number") + } else { + num = protowire.Number(n) + } + wtyp := protowire.Type(tag & 7) + + if wtyp == protowire.EndGroupType { + if num != groupTag { + return out, errors.New("mismatching end group marker") + } + groupTag = 0 + break + } + + var f *coderFieldInfo + if int(num) < len(mi.denseCoderFields) { + f = mi.denseCoderFields[num] + } else { + f = mi.coderFields[num] + } + var n int + err := errUnknown + discardUnknown := false + Field: + switch { + case f != nil: + if f.funcs.unmarshal == nil { + break + } + if f.isLazy && lazyDecode { + switch { + case lazyFields == nil || lazyFields[f] == lazyValidateOnly: + // Attempt to validate this field and leave it for later lazy unmarshaling. + o, valid := mi.skipField(b, f, wtyp, opts) + switch valid { + case ValidationValid: + // Skip over the valid field and continue. + err = nil + presence.SetPresentUnatomic(f.presenceIndex, mi.presenceSize) + requiredMask |= f.validation.requiredBit + if !o.initialized { + initialized = false + } + n = o.n + break Field + case ValidationInvalid: + return out, errors.New("invalid proto wire format") + case ValidationWrongWireType: + break Field + case ValidationUnknown: + if lazyFields == nil { + lazyFields = make(map[*coderFieldInfo]lazyAction) + } + if presence.Present(f.presenceIndex) { + // We were unable to determine if the field is valid or not, + // and we've already skipped over at least one instance of this + // field. Clear the presence bit (so if we stop decoding early, + // we don't leave a partially-initialized field around) and flag + // the field for unmarshaling before we return. + presence.ClearPresent(f.presenceIndex) + lazyFields[f] = lazyUnmarshalLater + discardUnknown = true + break Field + } else { + // We were unable to determine if the field is valid or not, + // but this is the first time we've seen it. Flag it as needing + // eager unmarshaling and fall through to the eager unmarshal case below. + lazyFields[f] = lazyUnmarshalNow + } + } + case lazyFields[f] == lazyUnmarshalLater: + // This field will be unmarshaled in a separate pass below. + // Skip over it here. + discardUnknown = true + break Field + default: + // Eagerly unmarshal the field. + } + } + if f.isLazy && !lazyDecode && presence.Present(f.presenceIndex) { + if p.Apply(f.offset).AtomicGetPointer().IsNil() { + mi.lazyUnmarshal(p, f.num) + } + } + var o unmarshalOutput + o, err = f.funcs.unmarshal(b, p.Apply(f.offset), wtyp, f, opts) + n = o.n + if err != nil { + break + } + requiredMask |= f.validation.requiredBit + if f.funcs.isInit != nil && !o.initialized { + initialized = false + } + if f.presenceIndex != noPresence { + presence.SetPresentUnatomic(f.presenceIndex, mi.presenceSize) + } + default: + // Possible extension. + if exts == nil && mi.extensionOffset.IsValid() { + exts = p.Apply(mi.extensionOffset).Extensions() + if *exts == nil { + *exts = make(map[int32]ExtensionField) + } + } + if exts == nil { + break + } + var o unmarshalOutput + o, err = mi.unmarshalExtension(b, num, wtyp, *exts, opts) + if err != nil { + break + } + n = o.n + if !o.initialized { + initialized = false + } + } + if err != nil { + if err != errUnknown { + return out, err + } + n = protowire.ConsumeFieldValue(num, wtyp, b) + if n < 0 { + return out, errDecode + } + if !discardUnknown && !opts.DiscardUnknown() && mi.unknownOffset.IsValid() { + u := mi.mutableUnknownBytes(p) + *u = protowire.AppendTag(*u, num, wtyp) + *u = append(*u, b[:n]...) + } + } + b = b[n:] + end := start - len(b) + if lazyDecode && f != nil && f.isLazy { + if num != lastNum { + lazyIndex = append(lazyIndex, protolazy.IndexEntry{ + FieldNum: uint32(num), + Start: uint32(pos), + End: uint32(end), + }) + } else { + i := len(lazyIndex) - 1 + lazyIndex[i].End = uint32(end) + lazyIndex[i].MultipleContiguous = true + } + } + if num < lastNum { + outOfOrder = true + } + pos = end + lastNum = num + } + if groupTag != 0 { + return out, errors.New("missing end group marker") + } + if lazyFields != nil { + // Some fields failed validation, and now need to be unmarshaled. + for f, action := range lazyFields { + if action != lazyUnmarshalLater { + continue + } + initialized = false + if *lazy == nil { + *lazy = &protolazy.XXX_lazyUnmarshalInfo{} + } + if err := mi.unmarshalField((*lazy).Buffer(), p.Apply(f.offset), f, *lazy, opts.flags); err != nil { + return out, err + } + presence.SetPresentUnatomic(f.presenceIndex, mi.presenceSize) + } + } + if lazyDecode { + if outOfOrder { + sort.Slice(lazyIndex, func(i, j int) bool { + return lazyIndex[i].FieldNum < lazyIndex[j].FieldNum || + (lazyIndex[i].FieldNum == lazyIndex[j].FieldNum && + lazyIndex[i].Start < lazyIndex[j].Start) + }) + } + if *lazy == nil { + *lazy = &protolazy.XXX_lazyUnmarshalInfo{} + } + + (*lazy).SetIndex(lazyIndex) + } + if mi.numRequiredFields > 0 && bits.OnesCount64(requiredMask) != int(mi.numRequiredFields) { + initialized = false + } + if initialized { + out.initialized = true + } + out.n = start - len(b) + return out, nil +} diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/impl/legacy_message.go b/go-controller/vendor/google.golang.org/protobuf/internal/impl/legacy_message.go index bf0b6049b4..a51dffbe29 100644 --- a/go-controller/vendor/google.golang.org/protobuf/internal/impl/legacy_message.go +++ b/go-controller/vendor/google.golang.org/protobuf/internal/impl/legacy_message.go @@ -310,12 +310,9 @@ func aberrantAppendField(md *filedesc.Message, goType reflect.Type, tag, tagKey, fd.L0.Parent = md fd.L0.Index = n - if fd.L1.IsWeak || fd.L1.EditionFeatures.IsPacked { + if fd.L1.EditionFeatures.IsPacked { fd.L1.Options = func() protoreflect.ProtoMessage { opts := descopts.Field.ProtoReflect().New() - if fd.L1.IsWeak { - opts.Set(opts.Descriptor().Fields().ByName("weak"), protoreflect.ValueOfBool(true)) - } if fd.L1.EditionFeatures.IsPacked { opts.Set(opts.Descriptor().Fields().ByName("packed"), protoreflect.ValueOfBool(fd.L1.EditionFeatures.IsPacked)) } diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/impl/merge.go b/go-controller/vendor/google.golang.org/protobuf/internal/impl/merge.go index 7e65f64f28..8ffdce67d3 100644 --- a/go-controller/vendor/google.golang.org/protobuf/internal/impl/merge.go +++ b/go-controller/vendor/google.golang.org/protobuf/internal/impl/merge.go @@ -41,11 +41,38 @@ func (mi *MessageInfo) mergePointer(dst, src pointer, opts mergeOptions) { if src.IsNil() { return } + + var presenceSrc presence + var presenceDst presence + if mi.presenceOffset.IsValid() { + presenceSrc = src.Apply(mi.presenceOffset).PresenceInfo() + presenceDst = dst.Apply(mi.presenceOffset).PresenceInfo() + } + for _, f := range mi.orderedCoderFields { if f.funcs.merge == nil { continue } sfptr := src.Apply(f.offset) + + if f.presenceIndex != noPresence { + if !presenceSrc.Present(f.presenceIndex) { + continue + } + dfptr := dst.Apply(f.offset) + if f.isLazy { + if sfptr.AtomicGetPointer().IsNil() { + mi.lazyUnmarshal(src, f.num) + } + if presenceDst.Present(f.presenceIndex) && dfptr.AtomicGetPointer().IsNil() { + mi.lazyUnmarshal(dst, f.num) + } + } + f.funcs.merge(dst.Apply(f.offset), sfptr, f, opts) + presenceDst.SetPresentUnatomic(f.presenceIndex, mi.presenceSize) + continue + } + if f.isPointer && sfptr.Elem().IsNil() { continue } diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/impl/message.go b/go-controller/vendor/google.golang.org/protobuf/internal/impl/message.go index 741b5ed29c..d50423dcb7 100644 --- a/go-controller/vendor/google.golang.org/protobuf/internal/impl/message.go +++ b/go-controller/vendor/google.golang.org/protobuf/internal/impl/message.go @@ -14,7 +14,6 @@ import ( "google.golang.org/protobuf/internal/genid" "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/reflect/protoregistry" ) // MessageInfo provides protobuf related functionality for a given Go type @@ -79,6 +78,9 @@ func (mi *MessageInfo) initOnce() { if mi.initDone == 1 { return } + if opaqueInitHook(mi) { + return + } t := mi.GoReflectType if t.Kind() != reflect.Ptr && t.Elem().Kind() != reflect.Struct { @@ -117,7 +119,6 @@ type ( var ( sizecacheType = reflect.TypeOf(SizeCache(0)) - weakFieldsType = reflect.TypeOf(WeakFields(nil)) unknownFieldsAType = reflect.TypeOf(unknownFieldsA(nil)) unknownFieldsBType = reflect.TypeOf(unknownFieldsB(nil)) extensionFieldsType = reflect.TypeOf(ExtensionFields(nil)) @@ -126,13 +127,14 @@ var ( type structInfo struct { sizecacheOffset offset sizecacheType reflect.Type - weakOffset offset - weakType reflect.Type unknownOffset offset unknownType reflect.Type extensionOffset offset extensionType reflect.Type + lazyOffset offset + presenceOffset offset + fieldsByNumber map[protoreflect.FieldNumber]reflect.StructField oneofsByName map[protoreflect.Name]reflect.StructField oneofWrappersByType map[reflect.Type]protoreflect.FieldNumber @@ -142,9 +144,10 @@ type structInfo struct { func (mi *MessageInfo) makeStructInfo(t reflect.Type) structInfo { si := structInfo{ sizecacheOffset: invalidOffset, - weakOffset: invalidOffset, unknownOffset: invalidOffset, extensionOffset: invalidOffset, + lazyOffset: invalidOffset, + presenceOffset: invalidOffset, fieldsByNumber: map[protoreflect.FieldNumber]reflect.StructField{}, oneofsByName: map[protoreflect.Name]reflect.StructField{}, @@ -157,24 +160,23 @@ fieldLoop: switch f := t.Field(i); f.Name { case genid.SizeCache_goname, genid.SizeCacheA_goname: if f.Type == sizecacheType { - si.sizecacheOffset = offsetOf(f, mi.Exporter) + si.sizecacheOffset = offsetOf(f) si.sizecacheType = f.Type } - case genid.WeakFields_goname, genid.WeakFieldsA_goname: - if f.Type == weakFieldsType { - si.weakOffset = offsetOf(f, mi.Exporter) - si.weakType = f.Type - } case genid.UnknownFields_goname, genid.UnknownFieldsA_goname: if f.Type == unknownFieldsAType || f.Type == unknownFieldsBType { - si.unknownOffset = offsetOf(f, mi.Exporter) + si.unknownOffset = offsetOf(f) si.unknownType = f.Type } case genid.ExtensionFields_goname, genid.ExtensionFieldsA_goname, genid.ExtensionFieldsB_goname: if f.Type == extensionFieldsType { - si.extensionOffset = offsetOf(f, mi.Exporter) + si.extensionOffset = offsetOf(f) si.extensionType = f.Type } + case "lazyFields", "XXX_lazyUnmarshalInfo": + si.lazyOffset = offsetOf(f) + case "XXX_presence": + si.presenceOffset = offsetOf(f) default: for _, s := range strings.Split(f.Tag.Get("protobuf"), ",") { if len(s) > 0 && strings.Trim(s, "0123456789") == "" { @@ -244,9 +246,6 @@ func (mi *MessageInfo) Message(i int) protoreflect.MessageType { mi.init() fd := mi.Desc.Fields().Get(i) switch { - case fd.IsWeak(): - mt, _ := protoregistry.GlobalTypes.FindMessageByName(fd.Message().FullName()) - return mt case fd.IsMap(): return mapEntryType{fd.Message(), mi.fieldTypes[fd.Number()]} default: diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/impl/message_opaque.go b/go-controller/vendor/google.golang.org/protobuf/internal/impl/message_opaque.go new file mode 100644 index 0000000000..dd55e8e009 --- /dev/null +++ b/go-controller/vendor/google.golang.org/protobuf/internal/impl/message_opaque.go @@ -0,0 +1,627 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package impl + +import ( + "fmt" + "math" + "reflect" + "strings" + "sync/atomic" + + "google.golang.org/protobuf/reflect/protoreflect" +) + +type opaqueStructInfo struct { + structInfo +} + +// isOpaque determines whether a protobuf message type is on the Opaque API. It +// checks whether the type is a Go struct that protoc-gen-go would generate. +// +// This function only detects newly generated messages from the v2 +// implementation of protoc-gen-go. It is unable to classify generated messages +// that are too old or those that are generated by a different generator +// such as protoc-gen-gogo. +func isOpaque(t reflect.Type) bool { + // The current detection mechanism is to simply check the first field + // for a struct tag with the "protogen" key. + if t.Kind() == reflect.Struct && t.NumField() > 0 { + pgt := t.Field(0).Tag.Get("protogen") + return strings.HasPrefix(pgt, "opaque.") + } + return false +} + +func opaqueInitHook(mi *MessageInfo) bool { + mt := mi.GoReflectType.Elem() + si := opaqueStructInfo{ + structInfo: mi.makeStructInfo(mt), + } + + if !isOpaque(mt) { + return false + } + + defer atomic.StoreUint32(&mi.initDone, 1) + + mi.fields = map[protoreflect.FieldNumber]*fieldInfo{} + fds := mi.Desc.Fields() + for i := 0; i < fds.Len(); i++ { + fd := fds.Get(i) + fs := si.fieldsByNumber[fd.Number()] + var fi fieldInfo + usePresence, _ := usePresenceForField(si, fd) + + switch { + case fd.ContainingOneof() != nil && !fd.ContainingOneof().IsSynthetic(): + // Oneofs are no different for opaque. + fi = fieldInfoForOneof(fd, si.oneofsByName[fd.ContainingOneof().Name()], mi.Exporter, si.oneofWrappersByNumber[fd.Number()]) + case fd.IsMap(): + fi = mi.fieldInfoForMapOpaque(si, fd, fs) + case fd.IsList() && fd.Message() == nil && usePresence: + fi = mi.fieldInfoForScalarListOpaque(si, fd, fs) + case fd.IsList() && fd.Message() == nil: + // Proto3 lists without presence can use same access methods as open + fi = fieldInfoForList(fd, fs, mi.Exporter) + case fd.IsList() && usePresence: + fi = mi.fieldInfoForMessageListOpaque(si, fd, fs) + case fd.IsList(): + // Proto3 opaque messages that does not need presence bitmap. + // Different representation than open struct, but same logic + fi = mi.fieldInfoForMessageListOpaqueNoPresence(si, fd, fs) + case fd.Message() != nil && usePresence: + fi = mi.fieldInfoForMessageOpaque(si, fd, fs) + case fd.Message() != nil: + // Proto3 messages without presence can use same access methods as open + fi = fieldInfoForMessage(fd, fs, mi.Exporter) + default: + fi = mi.fieldInfoForScalarOpaque(si, fd, fs) + } + mi.fields[fd.Number()] = &fi + } + mi.oneofs = map[protoreflect.Name]*oneofInfo{} + for i := 0; i < mi.Desc.Oneofs().Len(); i++ { + od := mi.Desc.Oneofs().Get(i) + mi.oneofs[od.Name()] = makeOneofInfoOpaque(mi, od, si.structInfo, mi.Exporter) + } + + mi.denseFields = make([]*fieldInfo, fds.Len()*2) + for i := 0; i < fds.Len(); i++ { + if fd := fds.Get(i); int(fd.Number()) < len(mi.denseFields) { + mi.denseFields[fd.Number()] = mi.fields[fd.Number()] + } + } + + for i := 0; i < fds.Len(); { + fd := fds.Get(i) + if od := fd.ContainingOneof(); od != nil && !fd.ContainingOneof().IsSynthetic() { + mi.rangeInfos = append(mi.rangeInfos, mi.oneofs[od.Name()]) + i += od.Fields().Len() + } else { + mi.rangeInfos = append(mi.rangeInfos, mi.fields[fd.Number()]) + i++ + } + } + + mi.makeExtensionFieldsFunc(mt, si.structInfo) + mi.makeUnknownFieldsFunc(mt, si.structInfo) + mi.makeOpaqueCoderMethods(mt, si) + mi.makeFieldTypes(si.structInfo) + + return true +} + +func makeOneofInfoOpaque(mi *MessageInfo, od protoreflect.OneofDescriptor, si structInfo, x exporter) *oneofInfo { + oi := &oneofInfo{oneofDesc: od} + if od.IsSynthetic() { + fd := od.Fields().Get(0) + index, _ := presenceIndex(mi.Desc, fd) + oi.which = func(p pointer) protoreflect.FieldNumber { + if p.IsNil() { + return 0 + } + if !mi.present(p, index) { + return 0 + } + return od.Fields().Get(0).Number() + } + return oi + } + // Dispatch to non-opaque oneof implementation for non-synthetic oneofs. + return makeOneofInfo(od, si, x) +} + +func (mi *MessageInfo) fieldInfoForMapOpaque(si opaqueStructInfo, fd protoreflect.FieldDescriptor, fs reflect.StructField) fieldInfo { + ft := fs.Type + if ft.Kind() != reflect.Map { + panic(fmt.Sprintf("invalid type: got %v, want map kind", ft)) + } + fieldOffset := offsetOf(fs) + conv := NewConverter(ft, fd) + return fieldInfo{ + fieldDesc: fd, + has: func(p pointer) bool { + if p.IsNil() { + return false + } + // Don't bother checking presence bits, since we need to + // look at the map length even if the presence bit is set. + rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() + return rv.Len() > 0 + }, + clear: func(p pointer) { + rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() + rv.Set(reflect.Zero(rv.Type())) + }, + get: func(p pointer) protoreflect.Value { + if p.IsNil() { + return conv.Zero() + } + rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() + if rv.Len() == 0 { + return conv.Zero() + } + return conv.PBValueOf(rv) + }, + set: func(p pointer, v protoreflect.Value) { + pv := conv.GoValueOf(v) + if pv.IsNil() { + panic(fmt.Sprintf("invalid value: setting map field to read-only value")) + } + rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() + rv.Set(pv) + }, + mutable: func(p pointer) protoreflect.Value { + v := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() + if v.IsNil() { + v.Set(reflect.MakeMap(fs.Type)) + } + return conv.PBValueOf(v) + }, + newField: func() protoreflect.Value { + return conv.New() + }, + } +} + +func (mi *MessageInfo) fieldInfoForScalarListOpaque(si opaqueStructInfo, fd protoreflect.FieldDescriptor, fs reflect.StructField) fieldInfo { + ft := fs.Type + if ft.Kind() != reflect.Slice { + panic(fmt.Sprintf("invalid type: got %v, want slice kind", ft)) + } + conv := NewConverter(reflect.PtrTo(ft), fd) + fieldOffset := offsetOf(fs) + index, _ := presenceIndex(mi.Desc, fd) + return fieldInfo{ + fieldDesc: fd, + has: func(p pointer) bool { + if p.IsNil() { + return false + } + rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() + return rv.Len() > 0 + }, + clear: func(p pointer) { + rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() + rv.Set(reflect.Zero(rv.Type())) + }, + get: func(p pointer) protoreflect.Value { + if p.IsNil() { + return conv.Zero() + } + rv := p.Apply(fieldOffset).AsValueOf(fs.Type) + if rv.Elem().Len() == 0 { + return conv.Zero() + } + return conv.PBValueOf(rv) + }, + set: func(p pointer, v protoreflect.Value) { + pv := conv.GoValueOf(v) + if pv.IsNil() { + panic(fmt.Sprintf("invalid value: setting repeated field to read-only value")) + } + mi.setPresent(p, index) + rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() + rv.Set(pv.Elem()) + }, + mutable: func(p pointer) protoreflect.Value { + mi.setPresent(p, index) + return conv.PBValueOf(p.Apply(fieldOffset).AsValueOf(fs.Type)) + }, + newField: func() protoreflect.Value { + return conv.New() + }, + } +} + +func (mi *MessageInfo) fieldInfoForMessageListOpaque(si opaqueStructInfo, fd protoreflect.FieldDescriptor, fs reflect.StructField) fieldInfo { + ft := fs.Type + if ft.Kind() != reflect.Ptr || ft.Elem().Kind() != reflect.Slice { + panic(fmt.Sprintf("invalid type: got %v, want slice kind", ft)) + } + conv := NewConverter(ft, fd) + fieldOffset := offsetOf(fs) + index, _ := presenceIndex(mi.Desc, fd) + fieldNumber := fd.Number() + return fieldInfo{ + fieldDesc: fd, + has: func(p pointer) bool { + if p.IsNil() { + return false + } + if !mi.present(p, index) { + return false + } + sp := p.Apply(fieldOffset).AtomicGetPointer() + if sp.IsNil() { + // Lazily unmarshal this field. + mi.lazyUnmarshal(p, fieldNumber) + sp = p.Apply(fieldOffset).AtomicGetPointer() + } + rv := sp.AsValueOf(fs.Type.Elem()) + return rv.Elem().Len() > 0 + }, + clear: func(p pointer) { + fp := p.Apply(fieldOffset) + sp := fp.AtomicGetPointer() + if sp.IsNil() { + sp = fp.AtomicSetPointerIfNil(pointerOfValue(reflect.New(fs.Type.Elem()))) + mi.setPresent(p, index) + } + rv := sp.AsValueOf(fs.Type.Elem()) + rv.Elem().Set(reflect.Zero(rv.Type().Elem())) + }, + get: func(p pointer) protoreflect.Value { + if p.IsNil() { + return conv.Zero() + } + if !mi.present(p, index) { + return conv.Zero() + } + sp := p.Apply(fieldOffset).AtomicGetPointer() + if sp.IsNil() { + // Lazily unmarshal this field. + mi.lazyUnmarshal(p, fieldNumber) + sp = p.Apply(fieldOffset).AtomicGetPointer() + } + rv := sp.AsValueOf(fs.Type.Elem()) + if rv.Elem().Len() == 0 { + return conv.Zero() + } + return conv.PBValueOf(rv) + }, + set: func(p pointer, v protoreflect.Value) { + fp := p.Apply(fieldOffset) + sp := fp.AtomicGetPointer() + if sp.IsNil() { + sp = fp.AtomicSetPointerIfNil(pointerOfValue(reflect.New(fs.Type.Elem()))) + mi.setPresent(p, index) + } + rv := sp.AsValueOf(fs.Type.Elem()) + val := conv.GoValueOf(v) + if val.IsNil() { + panic(fmt.Sprintf("invalid value: setting repeated field to read-only value")) + } else { + rv.Elem().Set(val.Elem()) + } + }, + mutable: func(p pointer) protoreflect.Value { + fp := p.Apply(fieldOffset) + sp := fp.AtomicGetPointer() + if sp.IsNil() { + if mi.present(p, index) { + // Lazily unmarshal this field. + mi.lazyUnmarshal(p, fieldNumber) + sp = p.Apply(fieldOffset).AtomicGetPointer() + } else { + sp = fp.AtomicSetPointerIfNil(pointerOfValue(reflect.New(fs.Type.Elem()))) + mi.setPresent(p, index) + } + } + rv := sp.AsValueOf(fs.Type.Elem()) + return conv.PBValueOf(rv) + }, + newField: func() protoreflect.Value { + return conv.New() + }, + } +} + +func (mi *MessageInfo) fieldInfoForMessageListOpaqueNoPresence(si opaqueStructInfo, fd protoreflect.FieldDescriptor, fs reflect.StructField) fieldInfo { + ft := fs.Type + if ft.Kind() != reflect.Ptr || ft.Elem().Kind() != reflect.Slice { + panic(fmt.Sprintf("invalid type: got %v, want slice kind", ft)) + } + conv := NewConverter(ft, fd) + fieldOffset := offsetOf(fs) + return fieldInfo{ + fieldDesc: fd, + has: func(p pointer) bool { + if p.IsNil() { + return false + } + sp := p.Apply(fieldOffset).AtomicGetPointer() + if sp.IsNil() { + return false + } + rv := sp.AsValueOf(fs.Type.Elem()) + return rv.Elem().Len() > 0 + }, + clear: func(p pointer) { + sp := p.Apply(fieldOffset).AtomicGetPointer() + if !sp.IsNil() { + rv := sp.AsValueOf(fs.Type.Elem()) + rv.Elem().Set(reflect.Zero(rv.Type().Elem())) + } + }, + get: func(p pointer) protoreflect.Value { + if p.IsNil() { + return conv.Zero() + } + sp := p.Apply(fieldOffset).AtomicGetPointer() + if sp.IsNil() { + return conv.Zero() + } + rv := sp.AsValueOf(fs.Type.Elem()) + if rv.Elem().Len() == 0 { + return conv.Zero() + } + return conv.PBValueOf(rv) + }, + set: func(p pointer, v protoreflect.Value) { + rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() + if rv.IsNil() { + rv.Set(reflect.New(fs.Type.Elem())) + } + val := conv.GoValueOf(v) + if val.IsNil() { + panic(fmt.Sprintf("invalid value: setting repeated field to read-only value")) + } else { + rv.Elem().Set(val.Elem()) + } + }, + mutable: func(p pointer) protoreflect.Value { + rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() + if rv.IsNil() { + rv.Set(reflect.New(fs.Type.Elem())) + } + return conv.PBValueOf(rv) + }, + newField: func() protoreflect.Value { + return conv.New() + }, + } +} + +func (mi *MessageInfo) fieldInfoForScalarOpaque(si opaqueStructInfo, fd protoreflect.FieldDescriptor, fs reflect.StructField) fieldInfo { + ft := fs.Type + nullable := fd.HasPresence() + if oneof := fd.ContainingOneof(); oneof != nil && oneof.IsSynthetic() { + nullable = true + } + deref := false + if nullable && ft.Kind() == reflect.Ptr { + ft = ft.Elem() + deref = true + } + conv := NewConverter(ft, fd) + fieldOffset := offsetOf(fs) + index, _ := presenceIndex(mi.Desc, fd) + var getter func(p pointer) protoreflect.Value + if !nullable { + getter = getterForDirectScalar(fd, fs, conv, fieldOffset) + } else { + getter = getterForOpaqueNullableScalar(mi, index, fd, fs, conv, fieldOffset) + } + return fieldInfo{ + fieldDesc: fd, + has: func(p pointer) bool { + if p.IsNil() { + return false + } + if nullable { + return mi.present(p, index) + } + rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() + switch rv.Kind() { + case reflect.Bool: + return rv.Bool() + case reflect.Int32, reflect.Int64: + return rv.Int() != 0 + case reflect.Uint32, reflect.Uint64: + return rv.Uint() != 0 + case reflect.Float32, reflect.Float64: + return rv.Float() != 0 || math.Signbit(rv.Float()) + case reflect.String, reflect.Slice: + return rv.Len() > 0 + default: + panic(fmt.Sprintf("invalid type: %v", rv.Type())) // should never happen + } + }, + clear: func(p pointer) { + if nullable { + mi.clearPresent(p, index) + } + // This is only valuable for bytes and strings, but we do it unconditionally. + rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() + rv.Set(reflect.Zero(rv.Type())) + }, + get: getter, + // TODO: Implement unsafe fast path for set? + set: func(p pointer, v protoreflect.Value) { + rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() + if deref { + if rv.IsNil() { + rv.Set(reflect.New(ft)) + } + rv = rv.Elem() + } + + rv.Set(conv.GoValueOf(v)) + if nullable && rv.Kind() == reflect.Slice && rv.IsNil() { + rv.Set(emptyBytes) + } + if nullable { + mi.setPresent(p, index) + } + }, + newField: func() protoreflect.Value { + return conv.New() + }, + } +} + +func (mi *MessageInfo) fieldInfoForMessageOpaque(si opaqueStructInfo, fd protoreflect.FieldDescriptor, fs reflect.StructField) fieldInfo { + ft := fs.Type + conv := NewConverter(ft, fd) + fieldOffset := offsetOf(fs) + index, _ := presenceIndex(mi.Desc, fd) + fieldNumber := fd.Number() + elemType := fs.Type.Elem() + return fieldInfo{ + fieldDesc: fd, + has: func(p pointer) bool { + if p.IsNil() { + return false + } + return mi.present(p, index) + }, + clear: func(p pointer) { + mi.clearPresent(p, index) + p.Apply(fieldOffset).AtomicSetNilPointer() + }, + get: func(p pointer) protoreflect.Value { + if p.IsNil() || !mi.present(p, index) { + return conv.Zero() + } + fp := p.Apply(fieldOffset) + mp := fp.AtomicGetPointer() + if mp.IsNil() { + // Lazily unmarshal this field. + mi.lazyUnmarshal(p, fieldNumber) + mp = fp.AtomicGetPointer() + } + rv := mp.AsValueOf(elemType) + return conv.PBValueOf(rv) + }, + set: func(p pointer, v protoreflect.Value) { + val := pointerOfValue(conv.GoValueOf(v)) + if val.IsNil() { + panic("invalid nil pointer") + } + p.Apply(fieldOffset).AtomicSetPointer(val) + mi.setPresent(p, index) + }, + mutable: func(p pointer) protoreflect.Value { + fp := p.Apply(fieldOffset) + mp := fp.AtomicGetPointer() + if mp.IsNil() { + if mi.present(p, index) { + // Lazily unmarshal this field. + mi.lazyUnmarshal(p, fieldNumber) + mp = fp.AtomicGetPointer() + } else { + mp = pointerOfValue(conv.GoValueOf(conv.New())) + fp.AtomicSetPointer(mp) + mi.setPresent(p, index) + } + } + return conv.PBValueOf(mp.AsValueOf(fs.Type.Elem())) + }, + newMessage: func() protoreflect.Message { + return conv.New().Message() + }, + newField: func() protoreflect.Value { + return conv.New() + }, + } +} + +// A presenceList wraps a List, updating presence bits as necessary when the +// list contents change. +type presenceList struct { + pvalueList + setPresence func(bool) +} +type pvalueList interface { + protoreflect.List + //Unwrapper +} + +func (list presenceList) Append(v protoreflect.Value) { + list.pvalueList.Append(v) + list.setPresence(true) +} +func (list presenceList) Truncate(i int) { + list.pvalueList.Truncate(i) + list.setPresence(i > 0) +} + +// presenceIndex returns the index to pass to presence functions. +// +// TODO: field.Desc.Index() would be simpler, and would give space to record the presence of oneof fields. +func presenceIndex(md protoreflect.MessageDescriptor, fd protoreflect.FieldDescriptor) (uint32, presenceSize) { + found := false + var index, numIndices uint32 + for i := 0; i < md.Fields().Len(); i++ { + f := md.Fields().Get(i) + if f == fd { + found = true + index = numIndices + } + if f.ContainingOneof() == nil || isLastOneofField(f) { + numIndices++ + } + } + if !found { + panic(fmt.Sprintf("BUG: %v not in %v", fd.Name(), md.FullName())) + } + return index, presenceSize(numIndices) +} + +func isLastOneofField(fd protoreflect.FieldDescriptor) bool { + fields := fd.ContainingOneof().Fields() + return fields.Get(fields.Len()-1) == fd +} + +func (mi *MessageInfo) setPresent(p pointer, index uint32) { + p.Apply(mi.presenceOffset).PresenceInfo().SetPresent(index, mi.presenceSize) +} + +func (mi *MessageInfo) clearPresent(p pointer, index uint32) { + p.Apply(mi.presenceOffset).PresenceInfo().ClearPresent(index) +} + +func (mi *MessageInfo) present(p pointer, index uint32) bool { + return p.Apply(mi.presenceOffset).PresenceInfo().Present(index) +} + +// usePresenceForField implements the somewhat intricate logic of when +// the presence bitmap is used for a field. The main logic is that a +// field that is optional or that can be lazy will use the presence +// bit, but for proto2, also maps have a presence bit. It also records +// if the field can ever be lazy, which is true if we have a +// lazyOffset and the field is a message or a slice of messages. A +// field that is lazy will always need a presence bit. Oneofs are not +// lazy and do not use presence, unless they are a synthetic oneof, +// which is a proto3 optional field. For proto3 optionals, we use the +// presence and they can also be lazy when applicable (a message). +func usePresenceForField(si opaqueStructInfo, fd protoreflect.FieldDescriptor) (usePresence, canBeLazy bool) { + hasLazyField := fd.(interface{ IsLazy() bool }).IsLazy() + + // Non-oneof scalar fields with explicit field presence use the presence array. + usesPresenceArray := fd.HasPresence() && fd.Message() == nil && (fd.ContainingOneof() == nil || fd.ContainingOneof().IsSynthetic()) + switch { + case fd.ContainingOneof() != nil && !fd.ContainingOneof().IsSynthetic(): + return false, false + case fd.IsMap(): + return false, false + case fd.Kind() == protoreflect.MessageKind || fd.Kind() == protoreflect.GroupKind: + return hasLazyField, hasLazyField + default: + return usesPresenceArray || (hasLazyField && fd.HasPresence()), false + } +} diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/impl/message_opaque_gen.go b/go-controller/vendor/google.golang.org/protobuf/internal/impl/message_opaque_gen.go new file mode 100644 index 0000000000..a69825699a --- /dev/null +++ b/go-controller/vendor/google.golang.org/protobuf/internal/impl/message_opaque_gen.go @@ -0,0 +1,132 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Code generated by generate-types. DO NOT EDIT. + +package impl + +import ( + "reflect" + + "google.golang.org/protobuf/reflect/protoreflect" +) + +func getterForOpaqueNullableScalar(mi *MessageInfo, index uint32, fd protoreflect.FieldDescriptor, fs reflect.StructField, conv Converter, fieldOffset offset) func(p pointer) protoreflect.Value { + ft := fs.Type + if ft.Kind() == reflect.Ptr { + ft = ft.Elem() + } + if fd.Kind() == protoreflect.EnumKind { + // Enums for nullable opaque types. + return func(p pointer) protoreflect.Value { + if p.IsNil() || !mi.present(p, index) { + return conv.Zero() + } + rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() + return conv.PBValueOf(rv) + } + } + switch ft.Kind() { + case reflect.Bool: + return func(p pointer) protoreflect.Value { + if p.IsNil() || !mi.present(p, index) { + return conv.Zero() + } + x := p.Apply(fieldOffset).Bool() + return protoreflect.ValueOfBool(*x) + } + case reflect.Int32: + return func(p pointer) protoreflect.Value { + if p.IsNil() || !mi.present(p, index) { + return conv.Zero() + } + x := p.Apply(fieldOffset).Int32() + return protoreflect.ValueOfInt32(*x) + } + case reflect.Uint32: + return func(p pointer) protoreflect.Value { + if p.IsNil() || !mi.present(p, index) { + return conv.Zero() + } + x := p.Apply(fieldOffset).Uint32() + return protoreflect.ValueOfUint32(*x) + } + case reflect.Int64: + return func(p pointer) protoreflect.Value { + if p.IsNil() || !mi.present(p, index) { + return conv.Zero() + } + x := p.Apply(fieldOffset).Int64() + return protoreflect.ValueOfInt64(*x) + } + case reflect.Uint64: + return func(p pointer) protoreflect.Value { + if p.IsNil() || !mi.present(p, index) { + return conv.Zero() + } + x := p.Apply(fieldOffset).Uint64() + return protoreflect.ValueOfUint64(*x) + } + case reflect.Float32: + return func(p pointer) protoreflect.Value { + if p.IsNil() || !mi.present(p, index) { + return conv.Zero() + } + x := p.Apply(fieldOffset).Float32() + return protoreflect.ValueOfFloat32(*x) + } + case reflect.Float64: + return func(p pointer) protoreflect.Value { + if p.IsNil() || !mi.present(p, index) { + return conv.Zero() + } + x := p.Apply(fieldOffset).Float64() + return protoreflect.ValueOfFloat64(*x) + } + case reflect.String: + if fd.Kind() == protoreflect.BytesKind { + return func(p pointer) protoreflect.Value { + if p.IsNil() || !mi.present(p, index) { + return conv.Zero() + } + x := p.Apply(fieldOffset).StringPtr() + if *x == nil { + return conv.Zero() + } + if len(**x) == 0 { + return protoreflect.ValueOfBytes(nil) + } + return protoreflect.ValueOfBytes([]byte(**x)) + } + } + return func(p pointer) protoreflect.Value { + if p.IsNil() || !mi.present(p, index) { + return conv.Zero() + } + x := p.Apply(fieldOffset).StringPtr() + if *x == nil { + return conv.Zero() + } + return protoreflect.ValueOfString(**x) + } + case reflect.Slice: + if fd.Kind() == protoreflect.StringKind { + return func(p pointer) protoreflect.Value { + if p.IsNil() || !mi.present(p, index) { + return conv.Zero() + } + x := p.Apply(fieldOffset).Bytes() + return protoreflect.ValueOfString(string(*x)) + } + } + return func(p pointer) protoreflect.Value { + if p.IsNil() || !mi.present(p, index) { + return conv.Zero() + } + x := p.Apply(fieldOffset).Bytes() + return protoreflect.ValueOfBytes(*x) + } + } + panic("unexpected protobuf kind: " + ft.Kind().String()) +} diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/impl/message_reflect.go b/go-controller/vendor/google.golang.org/protobuf/internal/impl/message_reflect.go index ecb4623d70..0d20132fa2 100644 --- a/go-controller/vendor/google.golang.org/protobuf/internal/impl/message_reflect.go +++ b/go-controller/vendor/google.golang.org/protobuf/internal/impl/message_reflect.go @@ -72,8 +72,6 @@ func (mi *MessageInfo) makeKnownFieldsFunc(si structInfo) { fi = fieldInfoForMap(fd, fs, mi.Exporter) case fd.IsList(): fi = fieldInfoForList(fd, fs, mi.Exporter) - case fd.IsWeak(): - fi = fieldInfoForWeakMessage(fd, si.weakOffset) case fd.Message() != nil: fi = fieldInfoForMessage(fd, fs, mi.Exporter) default: @@ -205,6 +203,11 @@ func (mi *MessageInfo) makeFieldTypes(si structInfo) { case fd.IsList(): if fd.Enum() != nil || fd.Message() != nil { ft = fs.Type.Elem() + + if ft.Kind() == reflect.Slice { + ft = ft.Elem() + } + } isMessage = fd.Message() != nil case fd.Enum() != nil: @@ -214,9 +217,6 @@ func (mi *MessageInfo) makeFieldTypes(si structInfo) { } case fd.Message() != nil: ft = fs.Type - if fd.IsWeak() { - ft = nil - } isMessage = true } if isMessage && ft != nil && ft.Kind() != reflect.Ptr { diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/impl/message_reflect_field.go b/go-controller/vendor/google.golang.org/protobuf/internal/impl/message_reflect_field.go index 986322b195..68d4ae32ec 100644 --- a/go-controller/vendor/google.golang.org/protobuf/internal/impl/message_reflect_field.go +++ b/go-controller/vendor/google.golang.org/protobuf/internal/impl/message_reflect_field.go @@ -8,11 +8,8 @@ import ( "fmt" "math" "reflect" - "sync" - "google.golang.org/protobuf/internal/flags" "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/reflect/protoregistry" ) type fieldInfo struct { @@ -76,7 +73,7 @@ func fieldInfoForOneof(fd protoreflect.FieldDescriptor, fs reflect.StructField, isMessage := fd.Message() != nil // TODO: Implement unsafe fast path? - fieldOffset := offsetOf(fs, x) + fieldOffset := offsetOf(fs) return fieldInfo{ // NOTE: The logic below intentionally assumes that oneof fields are // well-formatted. That is, the oneof interface never contains a @@ -152,7 +149,7 @@ func fieldInfoForMap(fd protoreflect.FieldDescriptor, fs reflect.StructField, x conv := NewConverter(ft, fd) // TODO: Implement unsafe fast path? - fieldOffset := offsetOf(fs, x) + fieldOffset := offsetOf(fs) return fieldInfo{ fieldDesc: fd, has: func(p pointer) bool { @@ -205,7 +202,7 @@ func fieldInfoForList(fd protoreflect.FieldDescriptor, fs reflect.StructField, x conv := NewConverter(reflect.PtrTo(ft), fd) // TODO: Implement unsafe fast path? - fieldOffset := offsetOf(fs, x) + fieldOffset := offsetOf(fs) return fieldInfo{ fieldDesc: fd, has: func(p pointer) bool { @@ -256,6 +253,7 @@ func fieldInfoForScalar(fd protoreflect.FieldDescriptor, fs reflect.StructField, ft := fs.Type nullable := fd.HasPresence() isBytes := ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 + var getter func(p pointer) protoreflect.Value if nullable { if ft.Kind() != reflect.Ptr && ft.Kind() != reflect.Slice { // This never occurs for generated message types. @@ -268,19 +266,25 @@ func fieldInfoForScalar(fd protoreflect.FieldDescriptor, fs reflect.StructField, } } conv := NewConverter(ft, fd) + fieldOffset := offsetOf(fs) + + // Generate specialized getter functions to avoid going through reflect.Value + if nullable { + getter = getterForNullableScalar(fd, fs, conv, fieldOffset) + } else { + getter = getterForDirectScalar(fd, fs, conv, fieldOffset) + } - // TODO: Implement unsafe fast path? - fieldOffset := offsetOf(fs, x) return fieldInfo{ fieldDesc: fd, has: func(p pointer) bool { if p.IsNil() { return false } - rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() if nullable { - return !rv.IsNil() + return !p.Apply(fieldOffset).Elem().IsNil() } + rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() switch rv.Kind() { case reflect.Bool: return rv.Bool() @@ -300,21 +304,8 @@ func fieldInfoForScalar(fd protoreflect.FieldDescriptor, fs reflect.StructField, rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() rv.Set(reflect.Zero(rv.Type())) }, - get: func(p pointer) protoreflect.Value { - if p.IsNil() { - return conv.Zero() - } - rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() - if nullable { - if rv.IsNil() { - return conv.Zero() - } - if rv.Kind() == reflect.Ptr { - rv = rv.Elem() - } - } - return conv.PBValueOf(rv) - }, + get: getter, + // TODO: Implement unsafe fast path for set? set: func(p pointer, v protoreflect.Value) { rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() if nullable && rv.Kind() == reflect.Ptr { @@ -338,85 +329,12 @@ func fieldInfoForScalar(fd protoreflect.FieldDescriptor, fs reflect.StructField, } } -func fieldInfoForWeakMessage(fd protoreflect.FieldDescriptor, weakOffset offset) fieldInfo { - if !flags.ProtoLegacy { - panic("no support for proto1 weak fields") - } - - var once sync.Once - var messageType protoreflect.MessageType - lazyInit := func() { - once.Do(func() { - messageName := fd.Message().FullName() - messageType, _ = protoregistry.GlobalTypes.FindMessageByName(messageName) - if messageType == nil { - panic(fmt.Sprintf("weak message %v for field %v is not linked in", messageName, fd.FullName())) - } - }) - } - - num := fd.Number() - return fieldInfo{ - fieldDesc: fd, - has: func(p pointer) bool { - if p.IsNil() { - return false - } - _, ok := p.Apply(weakOffset).WeakFields().get(num) - return ok - }, - clear: func(p pointer) { - p.Apply(weakOffset).WeakFields().clear(num) - }, - get: func(p pointer) protoreflect.Value { - lazyInit() - if p.IsNil() { - return protoreflect.ValueOfMessage(messageType.Zero()) - } - m, ok := p.Apply(weakOffset).WeakFields().get(num) - if !ok { - return protoreflect.ValueOfMessage(messageType.Zero()) - } - return protoreflect.ValueOfMessage(m.ProtoReflect()) - }, - set: func(p pointer, v protoreflect.Value) { - lazyInit() - m := v.Message() - if m.Descriptor() != messageType.Descriptor() { - if got, want := m.Descriptor().FullName(), messageType.Descriptor().FullName(); got != want { - panic(fmt.Sprintf("field %v has mismatching message descriptor: got %v, want %v", fd.FullName(), got, want)) - } - panic(fmt.Sprintf("field %v has mismatching message descriptor: %v", fd.FullName(), m.Descriptor().FullName())) - } - p.Apply(weakOffset).WeakFields().set(num, m.Interface()) - }, - mutable: func(p pointer) protoreflect.Value { - lazyInit() - fs := p.Apply(weakOffset).WeakFields() - m, ok := fs.get(num) - if !ok { - m = messageType.New().Interface() - fs.set(num, m) - } - return protoreflect.ValueOfMessage(m.ProtoReflect()) - }, - newMessage: func() protoreflect.Message { - lazyInit() - return messageType.New() - }, - newField: func() protoreflect.Value { - lazyInit() - return protoreflect.ValueOfMessage(messageType.New()) - }, - } -} - func fieldInfoForMessage(fd protoreflect.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo { ft := fs.Type conv := NewConverter(ft, fd) // TODO: Implement unsafe fast path? - fieldOffset := offsetOf(fs, x) + fieldOffset := offsetOf(fs) return fieldInfo{ fieldDesc: fd, has: func(p pointer) bool { @@ -425,7 +343,7 @@ func fieldInfoForMessage(fd protoreflect.FieldDescriptor, fs reflect.StructField } rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() if fs.Type.Kind() != reflect.Ptr { - return !isZero(rv) + return !rv.IsZero() } return !rv.IsNil() }, @@ -472,7 +390,7 @@ func makeOneofInfo(od protoreflect.OneofDescriptor, si structInfo, x exporter) * oi := &oneofInfo{oneofDesc: od} if od.IsSynthetic() { fs := si.fieldsByNumber[od.Fields().Get(0).Number()] - fieldOffset := offsetOf(fs, x) + fieldOffset := offsetOf(fs) oi.which = func(p pointer) protoreflect.FieldNumber { if p.IsNil() { return 0 @@ -485,7 +403,7 @@ func makeOneofInfo(od protoreflect.OneofDescriptor, si structInfo, x exporter) * } } else { fs := si.oneofsByName[od.Name()] - fieldOffset := offsetOf(fs, x) + fieldOffset := offsetOf(fs) oi.which = func(p pointer) protoreflect.FieldNumber { if p.IsNil() { return 0 @@ -503,41 +421,3 @@ func makeOneofInfo(od protoreflect.OneofDescriptor, si structInfo, x exporter) * } return oi } - -// isZero is identical to reflect.Value.IsZero. -// TODO: Remove this when Go1.13 is the minimally supported Go version. -func isZero(v reflect.Value) bool { - switch v.Kind() { - case reflect.Bool: - return !v.Bool() - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return v.Int() == 0 - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - return v.Uint() == 0 - case reflect.Float32, reflect.Float64: - return math.Float64bits(v.Float()) == 0 - case reflect.Complex64, reflect.Complex128: - c := v.Complex() - return math.Float64bits(real(c)) == 0 && math.Float64bits(imag(c)) == 0 - case reflect.Array: - for i := 0; i < v.Len(); i++ { - if !isZero(v.Index(i)) { - return false - } - } - return true - case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice, reflect.UnsafePointer: - return v.IsNil() - case reflect.String: - return v.Len() == 0 - case reflect.Struct: - for i := 0; i < v.NumField(); i++ { - if !isZero(v.Field(i)) { - return false - } - } - return true - default: - panic(&reflect.ValueError{Method: "reflect.Value.IsZero", Kind: v.Kind()}) - } -} diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/impl/message_reflect_field_gen.go b/go-controller/vendor/google.golang.org/protobuf/internal/impl/message_reflect_field_gen.go new file mode 100644 index 0000000000..af5e063a1e --- /dev/null +++ b/go-controller/vendor/google.golang.org/protobuf/internal/impl/message_reflect_field_gen.go @@ -0,0 +1,273 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Code generated by generate-types. DO NOT EDIT. + +package impl + +import ( + "reflect" + + "google.golang.org/protobuf/reflect/protoreflect" +) + +func getterForNullableScalar(fd protoreflect.FieldDescriptor, fs reflect.StructField, conv Converter, fieldOffset offset) func(p pointer) protoreflect.Value { + ft := fs.Type + if ft.Kind() == reflect.Ptr { + ft = ft.Elem() + } + if fd.Kind() == protoreflect.EnumKind { + elemType := fs.Type.Elem() + // Enums for nullable types. + return func(p pointer) protoreflect.Value { + if p.IsNil() { + return conv.Zero() + } + rv := p.Apply(fieldOffset).Elem().AsValueOf(elemType) + if rv.IsNil() { + return conv.Zero() + } + return conv.PBValueOf(rv.Elem()) + } + } + switch ft.Kind() { + case reflect.Bool: + return func(p pointer) protoreflect.Value { + if p.IsNil() { + return conv.Zero() + } + x := p.Apply(fieldOffset).BoolPtr() + if *x == nil { + return conv.Zero() + } + return protoreflect.ValueOfBool(**x) + } + case reflect.Int32: + return func(p pointer) protoreflect.Value { + if p.IsNil() { + return conv.Zero() + } + x := p.Apply(fieldOffset).Int32Ptr() + if *x == nil { + return conv.Zero() + } + return protoreflect.ValueOfInt32(**x) + } + case reflect.Uint32: + return func(p pointer) protoreflect.Value { + if p.IsNil() { + return conv.Zero() + } + x := p.Apply(fieldOffset).Uint32Ptr() + if *x == nil { + return conv.Zero() + } + return protoreflect.ValueOfUint32(**x) + } + case reflect.Int64: + return func(p pointer) protoreflect.Value { + if p.IsNil() { + return conv.Zero() + } + x := p.Apply(fieldOffset).Int64Ptr() + if *x == nil { + return conv.Zero() + } + return protoreflect.ValueOfInt64(**x) + } + case reflect.Uint64: + return func(p pointer) protoreflect.Value { + if p.IsNil() { + return conv.Zero() + } + x := p.Apply(fieldOffset).Uint64Ptr() + if *x == nil { + return conv.Zero() + } + return protoreflect.ValueOfUint64(**x) + } + case reflect.Float32: + return func(p pointer) protoreflect.Value { + if p.IsNil() { + return conv.Zero() + } + x := p.Apply(fieldOffset).Float32Ptr() + if *x == nil { + return conv.Zero() + } + return protoreflect.ValueOfFloat32(**x) + } + case reflect.Float64: + return func(p pointer) protoreflect.Value { + if p.IsNil() { + return conv.Zero() + } + x := p.Apply(fieldOffset).Float64Ptr() + if *x == nil { + return conv.Zero() + } + return protoreflect.ValueOfFloat64(**x) + } + case reflect.String: + if fd.Kind() == protoreflect.BytesKind { + return func(p pointer) protoreflect.Value { + if p.IsNil() { + return conv.Zero() + } + x := p.Apply(fieldOffset).StringPtr() + if *x == nil { + return conv.Zero() + } + if len(**x) == 0 { + return protoreflect.ValueOfBytes(nil) + } + return protoreflect.ValueOfBytes([]byte(**x)) + } + } + return func(p pointer) protoreflect.Value { + if p.IsNil() { + return conv.Zero() + } + x := p.Apply(fieldOffset).StringPtr() + if *x == nil { + return conv.Zero() + } + return protoreflect.ValueOfString(**x) + } + case reflect.Slice: + if fd.Kind() == protoreflect.StringKind { + return func(p pointer) protoreflect.Value { + if p.IsNil() { + return conv.Zero() + } + x := p.Apply(fieldOffset).Bytes() + if len(*x) == 0 { + return conv.Zero() + } + return protoreflect.ValueOfString(string(*x)) + } + } + return func(p pointer) protoreflect.Value { + if p.IsNil() { + return conv.Zero() + } + x := p.Apply(fieldOffset).Bytes() + if *x == nil { + return conv.Zero() + } + return protoreflect.ValueOfBytes(*x) + } + } + panic("unexpected protobuf kind: " + ft.Kind().String()) +} + +func getterForDirectScalar(fd protoreflect.FieldDescriptor, fs reflect.StructField, conv Converter, fieldOffset offset) func(p pointer) protoreflect.Value { + ft := fs.Type + if fd.Kind() == protoreflect.EnumKind { + // Enums for non nullable types. + return func(p pointer) protoreflect.Value { + if p.IsNil() { + return conv.Zero() + } + rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() + return conv.PBValueOf(rv) + } + } + switch ft.Kind() { + case reflect.Bool: + return func(p pointer) protoreflect.Value { + if p.IsNil() { + return conv.Zero() + } + x := p.Apply(fieldOffset).Bool() + return protoreflect.ValueOfBool(*x) + } + case reflect.Int32: + return func(p pointer) protoreflect.Value { + if p.IsNil() { + return conv.Zero() + } + x := p.Apply(fieldOffset).Int32() + return protoreflect.ValueOfInt32(*x) + } + case reflect.Uint32: + return func(p pointer) protoreflect.Value { + if p.IsNil() { + return conv.Zero() + } + x := p.Apply(fieldOffset).Uint32() + return protoreflect.ValueOfUint32(*x) + } + case reflect.Int64: + return func(p pointer) protoreflect.Value { + if p.IsNil() { + return conv.Zero() + } + x := p.Apply(fieldOffset).Int64() + return protoreflect.ValueOfInt64(*x) + } + case reflect.Uint64: + return func(p pointer) protoreflect.Value { + if p.IsNil() { + return conv.Zero() + } + x := p.Apply(fieldOffset).Uint64() + return protoreflect.ValueOfUint64(*x) + } + case reflect.Float32: + return func(p pointer) protoreflect.Value { + if p.IsNil() { + return conv.Zero() + } + x := p.Apply(fieldOffset).Float32() + return protoreflect.ValueOfFloat32(*x) + } + case reflect.Float64: + return func(p pointer) protoreflect.Value { + if p.IsNil() { + return conv.Zero() + } + x := p.Apply(fieldOffset).Float64() + return protoreflect.ValueOfFloat64(*x) + } + case reflect.String: + if fd.Kind() == protoreflect.BytesKind { + return func(p pointer) protoreflect.Value { + if p.IsNil() { + return conv.Zero() + } + x := p.Apply(fieldOffset).String() + if len(*x) == 0 { + return protoreflect.ValueOfBytes(nil) + } + return protoreflect.ValueOfBytes([]byte(*x)) + } + } + return func(p pointer) protoreflect.Value { + if p.IsNil() { + return conv.Zero() + } + x := p.Apply(fieldOffset).String() + return protoreflect.ValueOfString(*x) + } + case reflect.Slice: + if fd.Kind() == protoreflect.StringKind { + return func(p pointer) protoreflect.Value { + if p.IsNil() { + return conv.Zero() + } + x := p.Apply(fieldOffset).Bytes() + return protoreflect.ValueOfString(string(*x)) + } + } + return func(p pointer) protoreflect.Value { + if p.IsNil() { + return conv.Zero() + } + x := p.Apply(fieldOffset).Bytes() + return protoreflect.ValueOfBytes(*x) + } + } + panic("unexpected protobuf kind: " + ft.Kind().String()) +} diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/impl/pointer_unsafe.go b/go-controller/vendor/google.golang.org/protobuf/internal/impl/pointer_unsafe.go index 79e186667b..62f8bf663e 100644 --- a/go-controller/vendor/google.golang.org/protobuf/internal/impl/pointer_unsafe.go +++ b/go-controller/vendor/google.golang.org/protobuf/internal/impl/pointer_unsafe.go @@ -8,6 +8,8 @@ import ( "reflect" "sync/atomic" "unsafe" + + "google.golang.org/protobuf/internal/protolazy" ) const UnsafeEnabled = true @@ -20,7 +22,7 @@ type Pointer unsafe.Pointer type offset uintptr // offsetOf returns a field offset for the struct field. -func offsetOf(f reflect.StructField, x exporter) offset { +func offsetOf(f reflect.StructField) offset { return offset(f.Offset) } @@ -109,8 +111,14 @@ func (p pointer) StringSlice() *[]string { return (*[]string)(p.p func (p pointer) Bytes() *[]byte { return (*[]byte)(p.p) } func (p pointer) BytesPtr() **[]byte { return (**[]byte)(p.p) } func (p pointer) BytesSlice() *[][]byte { return (*[][]byte)(p.p) } -func (p pointer) WeakFields() *weakFields { return (*weakFields)(p.p) } func (p pointer) Extensions() *map[int32]ExtensionField { return (*map[int32]ExtensionField)(p.p) } +func (p pointer) LazyInfoPtr() **protolazy.XXX_lazyUnmarshalInfo { + return (**protolazy.XXX_lazyUnmarshalInfo)(p.p) +} + +func (p pointer) PresenceInfo() presence { + return presence{P: p.p} +} func (p pointer) Elem() pointer { return pointer{p: *(*unsafe.Pointer)(p.p)} diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/impl/pointer_unsafe_opaque.go b/go-controller/vendor/google.golang.org/protobuf/internal/impl/pointer_unsafe_opaque.go new file mode 100644 index 0000000000..38aa7b7dcf --- /dev/null +++ b/go-controller/vendor/google.golang.org/protobuf/internal/impl/pointer_unsafe_opaque.go @@ -0,0 +1,42 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package impl + +import ( + "sync/atomic" + "unsafe" +) + +func (p pointer) AtomicGetPointer() pointer { + return pointer{p: atomic.LoadPointer((*unsafe.Pointer)(p.p))} +} + +func (p pointer) AtomicSetPointer(v pointer) { + atomic.StorePointer((*unsafe.Pointer)(p.p), v.p) +} + +func (p pointer) AtomicSetNilPointer() { + atomic.StorePointer((*unsafe.Pointer)(p.p), unsafe.Pointer(nil)) +} + +func (p pointer) AtomicSetPointerIfNil(v pointer) pointer { + if atomic.CompareAndSwapPointer((*unsafe.Pointer)(p.p), unsafe.Pointer(nil), v.p) { + return v + } + return pointer{p: atomic.LoadPointer((*unsafe.Pointer)(p.p))} +} + +type atomicV1MessageInfo struct{ p Pointer } + +func (mi *atomicV1MessageInfo) Get() Pointer { + return Pointer(atomic.LoadPointer((*unsafe.Pointer)(&mi.p))) +} + +func (mi *atomicV1MessageInfo) SetIfNil(p Pointer) Pointer { + if atomic.CompareAndSwapPointer((*unsafe.Pointer)(&mi.p), nil, unsafe.Pointer(p)) { + return p + } + return mi.Get() +} diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/impl/presence.go b/go-controller/vendor/google.golang.org/protobuf/internal/impl/presence.go new file mode 100644 index 0000000000..914cb1deda --- /dev/null +++ b/go-controller/vendor/google.golang.org/protobuf/internal/impl/presence.go @@ -0,0 +1,142 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package impl + +import ( + "sync/atomic" + "unsafe" +) + +// presenceSize represents the size of a presence set, which should be the largest index of the set+1 +type presenceSize uint32 + +// presence is the internal representation of the bitmap array in a generated protobuf +type presence struct { + // This is a pointer to the beginning of an array of uint32 + P unsafe.Pointer +} + +func (p presence) toElem(num uint32) (ret *uint32) { + const ( + bitsPerByte = 8 + siz = unsafe.Sizeof(*ret) + ) + // p.P points to an array of uint32, num is the bit in this array that the + // caller wants to check/manipulate. Calculate the index in the array that + // contains this specific bit. E.g.: 76 / 32 = 2 (integer division). + offset := uintptr(num) / (siz * bitsPerByte) * siz + return (*uint32)(unsafe.Pointer(uintptr(p.P) + offset)) +} + +// Present checks for the presence of a specific field number in a presence set. +func (p presence) Present(num uint32) bool { + if p.P == nil { + return false + } + return Export{}.Present(p.toElem(num), num) +} + +// SetPresent adds presence for a specific field number in a presence set. +func (p presence) SetPresent(num uint32, size presenceSize) { + Export{}.SetPresent(p.toElem(num), num, uint32(size)) +} + +// SetPresentUnatomic adds presence for a specific field number in a presence set without using +// atomic operations. Only to be called during unmarshaling. +func (p presence) SetPresentUnatomic(num uint32, size presenceSize) { + Export{}.SetPresentNonAtomic(p.toElem(num), num, uint32(size)) +} + +// ClearPresent removes presence for a specific field number in a presence set. +func (p presence) ClearPresent(num uint32) { + Export{}.ClearPresent(p.toElem(num), num) +} + +// LoadPresenceCache (together with PresentInCache) allows for a +// cached version of checking for presence without re-reading the word +// for every field. It is optimized for efficiency and assumes no +// simltaneous mutation of the presence set (or at least does not have +// a problem with simultaneous mutation giving inconsistent results). +func (p presence) LoadPresenceCache() (current uint32) { + if p.P == nil { + return 0 + } + return atomic.LoadUint32((*uint32)(p.P)) +} + +// PresentInCache reads presence from a cached word in the presence +// bitmap. It caches up a new word if the bit is outside the +// word. This is for really fast iteration through bitmaps in cases +// where we either know that the bitmap will not be altered, or we +// don't care about inconsistencies caused by simultaneous writes. +func (p presence) PresentInCache(num uint32, cachedElement *uint32, current *uint32) bool { + if num/32 != *cachedElement { + o := uintptr(num/32) * unsafe.Sizeof(uint32(0)) + q := (*uint32)(unsafe.Pointer(uintptr(p.P) + o)) + *current = atomic.LoadUint32(q) + *cachedElement = num / 32 + } + return (*current & (1 << (num % 32))) > 0 +} + +// AnyPresent checks if any field is marked as present in the bitmap. +func (p presence) AnyPresent(size presenceSize) bool { + n := uintptr((size + 31) / 32) + for j := uintptr(0); j < n; j++ { + o := j * unsafe.Sizeof(uint32(0)) + q := (*uint32)(unsafe.Pointer(uintptr(p.P) + o)) + b := atomic.LoadUint32(q) + if b > 0 { + return true + } + } + return false +} + +// toRaceDetectData finds the preceding RaceDetectHookData in a +// message by using pointer arithmetic. As the type of the presence +// set (bitmap) varies with the number of fields in the protobuf, we +// can not have a struct type containing the array and the +// RaceDetectHookData. instead the RaceDetectHookData is placed +// immediately before the bitmap array, and we find it by walking +// backwards in the struct. +// +// This method is only called from the race-detect version of the code, +// so RaceDetectHookData is never an empty struct. +func (p presence) toRaceDetectData() *RaceDetectHookData { + var template struct { + d RaceDetectHookData + a [1]uint32 + } + o := (uintptr(unsafe.Pointer(&template.a)) - uintptr(unsafe.Pointer(&template.d))) + return (*RaceDetectHookData)(unsafe.Pointer(uintptr(p.P) - o)) +} + +func atomicLoadShadowPresence(p **[]byte) *[]byte { + return (*[]byte)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p)))) +} +func atomicStoreShadowPresence(p **[]byte, v *[]byte) { + atomic.CompareAndSwapPointer((*unsafe.Pointer)(unsafe.Pointer(p)), nil, unsafe.Pointer(v)) +} + +// findPointerToRaceDetectData finds the preceding RaceDetectHookData +// in a message by using pointer arithmetic. For the methods called +// directy from generated code, we don't have a pointer to the +// beginning of the presence set, but a pointer inside the array. As +// we know the index of the bit we're manipulating (num), we can +// calculate which element of the array ptr is pointing to. With that +// information we find the preceding RaceDetectHookData and can +// manipulate the shadow bitmap. +// +// This method is only called from the race-detect version of the +// code, so RaceDetectHookData is never an empty struct. +func findPointerToRaceDetectData(ptr *uint32, num uint32) *RaceDetectHookData { + var template struct { + d RaceDetectHookData + a [1]uint32 + } + o := (uintptr(unsafe.Pointer(&template.a)) - uintptr(unsafe.Pointer(&template.d))) + uintptr(num/32)*unsafe.Sizeof(uint32(0)) + return (*RaceDetectHookData)(unsafe.Pointer(uintptr(unsafe.Pointer(ptr)) - o)) +} diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/impl/validate.go b/go-controller/vendor/google.golang.org/protobuf/internal/impl/validate.go index a24e6bbd7a..7b2995dde5 100644 --- a/go-controller/vendor/google.golang.org/protobuf/internal/impl/validate.go +++ b/go-controller/vendor/google.golang.org/protobuf/internal/impl/validate.go @@ -37,6 +37,10 @@ const ( // ValidationValid indicates that unmarshaling the message will succeed. ValidationValid + + // ValidationWrongWireType indicates that a validated field does not have + // the expected wire type. + ValidationWrongWireType ) func (v ValidationStatus) String() string { @@ -149,11 +153,23 @@ func newValidationInfo(fd protoreflect.FieldDescriptor, ft reflect.Type) validat switch fd.Kind() { case protoreflect.MessageKind: vi.typ = validationTypeMessage + + if ft.Kind() == reflect.Ptr { + // Repeated opaque message fields are *[]*T. + ft = ft.Elem() + } + if ft.Kind() == reflect.Slice { vi.mi = getMessageInfo(ft.Elem()) } case protoreflect.GroupKind: vi.typ = validationTypeGroup + + if ft.Kind() == reflect.Ptr { + // Repeated opaque message fields are *[]*T. + ft = ft.Elem() + } + if ft.Kind() == reflect.Slice { vi.mi = getMessageInfo(ft.Elem()) } @@ -195,9 +211,7 @@ func newValidationInfo(fd protoreflect.FieldDescriptor, ft reflect.Type) validat switch fd.Kind() { case protoreflect.MessageKind: vi.typ = validationTypeMessage - if !fd.IsWeak() { - vi.mi = getMessageInfo(ft) - } + vi.mi = getMessageInfo(ft) case protoreflect.GroupKind: vi.typ = validationTypeGroup vi.mi = getMessageInfo(ft) @@ -304,26 +318,6 @@ State: } if f != nil { vi = f.validation - if vi.typ == validationTypeMessage && vi.mi == nil { - // Probable weak field. - // - // TODO: Consider storing the results of this lookup somewhere - // rather than recomputing it on every validation. - fd := st.mi.Desc.Fields().ByNumber(num) - if fd == nil || !fd.IsWeak() { - break - } - messageName := fd.Message().FullName() - messageType, err := protoregistry.GlobalTypes.FindMessageByName(messageName) - switch err { - case nil: - vi.mi, _ = messageType.(*MessageInfo) - case protoregistry.NotFound: - vi.typ = validationTypeBytes - default: - return out, ValidationUnknown - } - } break } // Possible extension field. diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/impl/weak.go b/go-controller/vendor/google.golang.org/protobuf/internal/impl/weak.go deleted file mode 100644 index eb79a7ba94..0000000000 --- a/go-controller/vendor/google.golang.org/protobuf/internal/impl/weak.go +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package impl - -import ( - "fmt" - - "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/reflect/protoregistry" -) - -// weakFields adds methods to the exported WeakFields type for internal use. -// -// The exported type is an alias to an unnamed type, so methods can't be -// defined directly on it. -type weakFields WeakFields - -func (w weakFields) get(num protoreflect.FieldNumber) (protoreflect.ProtoMessage, bool) { - m, ok := w[int32(num)] - return m, ok -} - -func (w *weakFields) set(num protoreflect.FieldNumber, m protoreflect.ProtoMessage) { - if *w == nil { - *w = make(weakFields) - } - (*w)[int32(num)] = m -} - -func (w *weakFields) clear(num protoreflect.FieldNumber) { - delete(*w, int32(num)) -} - -func (Export) HasWeak(w WeakFields, num protoreflect.FieldNumber) bool { - _, ok := w[int32(num)] - return ok -} - -func (Export) ClearWeak(w *WeakFields, num protoreflect.FieldNumber) { - delete(*w, int32(num)) -} - -func (Export) GetWeak(w WeakFields, num protoreflect.FieldNumber, name protoreflect.FullName) protoreflect.ProtoMessage { - if m, ok := w[int32(num)]; ok { - return m - } - mt, _ := protoregistry.GlobalTypes.FindMessageByName(name) - if mt == nil { - panic(fmt.Sprintf("message %v for weak field is not linked in", name)) - } - return mt.Zero().Interface() -} - -func (Export) SetWeak(w *WeakFields, num protoreflect.FieldNumber, name protoreflect.FullName, m protoreflect.ProtoMessage) { - if m != nil { - mt, _ := protoregistry.GlobalTypes.FindMessageByName(name) - if mt == nil { - panic(fmt.Sprintf("message %v for weak field is not linked in", name)) - } - if mt != m.ProtoReflect().Type() { - panic(fmt.Sprintf("invalid message type for weak field: got %T, want %T", m, mt.Zero().Interface())) - } - } - if m == nil || !m.ProtoReflect().IsValid() { - delete(*w, int32(num)) - return - } - if *w == nil { - *w = make(weakFields) - } - (*w)[int32(num)] = m -} diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/protolazy/bufferreader.go b/go-controller/vendor/google.golang.org/protobuf/internal/protolazy/bufferreader.go new file mode 100644 index 0000000000..82e5cab4aa --- /dev/null +++ b/go-controller/vendor/google.golang.org/protobuf/internal/protolazy/bufferreader.go @@ -0,0 +1,364 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Helper code for parsing a protocol buffer + +package protolazy + +import ( + "errors" + "fmt" + "io" + + "google.golang.org/protobuf/encoding/protowire" +) + +// BufferReader is a structure encapsulating a protobuf and a current position +type BufferReader struct { + Buf []byte + Pos int +} + +// NewBufferReader creates a new BufferRead from a protobuf +func NewBufferReader(buf []byte) BufferReader { + return BufferReader{Buf: buf, Pos: 0} +} + +var errOutOfBounds = errors.New("protobuf decoding: out of bounds") +var errOverflow = errors.New("proto: integer overflow") + +func (b *BufferReader) DecodeVarintSlow() (x uint64, err error) { + i := b.Pos + l := len(b.Buf) + + for shift := uint(0); shift < 64; shift += 7 { + if i >= l { + err = io.ErrUnexpectedEOF + return + } + v := b.Buf[i] + i++ + x |= (uint64(v) & 0x7F) << shift + if v < 0x80 { + b.Pos = i + return + } + } + + // The number is too large to represent in a 64-bit value. + err = errOverflow + return +} + +// decodeVarint decodes a varint at the current position +func (b *BufferReader) DecodeVarint() (x uint64, err error) { + i := b.Pos + buf := b.Buf + + if i >= len(buf) { + return 0, io.ErrUnexpectedEOF + } else if buf[i] < 0x80 { + b.Pos++ + return uint64(buf[i]), nil + } else if len(buf)-i < 10 { + return b.DecodeVarintSlow() + } + + var v uint64 + // we already checked the first byte + x = uint64(buf[i]) & 127 + i++ + + v = uint64(buf[i]) + i++ + x |= (v & 127) << 7 + if v < 128 { + goto done + } + + v = uint64(buf[i]) + i++ + x |= (v & 127) << 14 + if v < 128 { + goto done + } + + v = uint64(buf[i]) + i++ + x |= (v & 127) << 21 + if v < 128 { + goto done + } + + v = uint64(buf[i]) + i++ + x |= (v & 127) << 28 + if v < 128 { + goto done + } + + v = uint64(buf[i]) + i++ + x |= (v & 127) << 35 + if v < 128 { + goto done + } + + v = uint64(buf[i]) + i++ + x |= (v & 127) << 42 + if v < 128 { + goto done + } + + v = uint64(buf[i]) + i++ + x |= (v & 127) << 49 + if v < 128 { + goto done + } + + v = uint64(buf[i]) + i++ + x |= (v & 127) << 56 + if v < 128 { + goto done + } + + v = uint64(buf[i]) + i++ + x |= (v & 127) << 63 + if v < 128 { + goto done + } + + return 0, errOverflow + +done: + b.Pos = i + return +} + +// decodeVarint32 decodes a varint32 at the current position +func (b *BufferReader) DecodeVarint32() (x uint32, err error) { + i := b.Pos + buf := b.Buf + + if i >= len(buf) { + return 0, io.ErrUnexpectedEOF + } else if buf[i] < 0x80 { + b.Pos++ + return uint32(buf[i]), nil + } else if len(buf)-i < 5 { + v, err := b.DecodeVarintSlow() + return uint32(v), err + } + + var v uint32 + // we already checked the first byte + x = uint32(buf[i]) & 127 + i++ + + v = uint32(buf[i]) + i++ + x |= (v & 127) << 7 + if v < 128 { + goto done + } + + v = uint32(buf[i]) + i++ + x |= (v & 127) << 14 + if v < 128 { + goto done + } + + v = uint32(buf[i]) + i++ + x |= (v & 127) << 21 + if v < 128 { + goto done + } + + v = uint32(buf[i]) + i++ + x |= (v & 127) << 28 + if v < 128 { + goto done + } + + return 0, errOverflow + +done: + b.Pos = i + return +} + +// skipValue skips a value in the protobuf, based on the specified tag +func (b *BufferReader) SkipValue(tag uint32) (err error) { + wireType := tag & 0x7 + switch protowire.Type(wireType) { + case protowire.VarintType: + err = b.SkipVarint() + case protowire.Fixed64Type: + err = b.SkipFixed64() + case protowire.BytesType: + var n uint32 + n, err = b.DecodeVarint32() + if err == nil { + err = b.Skip(int(n)) + } + case protowire.StartGroupType: + err = b.SkipGroup(tag) + case protowire.Fixed32Type: + err = b.SkipFixed32() + default: + err = fmt.Errorf("Unexpected wire type (%d)", wireType) + } + return +} + +// skipGroup skips a group with the specified tag. It executes efficiently using a tag stack +func (b *BufferReader) SkipGroup(tag uint32) (err error) { + tagStack := make([]uint32, 0, 16) + tagStack = append(tagStack, tag) + var n uint32 + for len(tagStack) > 0 { + tag, err = b.DecodeVarint32() + if err != nil { + return err + } + switch protowire.Type(tag & 0x7) { + case protowire.VarintType: + err = b.SkipVarint() + case protowire.Fixed64Type: + err = b.Skip(8) + case protowire.BytesType: + n, err = b.DecodeVarint32() + if err == nil { + err = b.Skip(int(n)) + } + case protowire.StartGroupType: + tagStack = append(tagStack, tag) + case protowire.Fixed32Type: + err = b.SkipFixed32() + case protowire.EndGroupType: + if protoFieldNumber(tagStack[len(tagStack)-1]) == protoFieldNumber(tag) { + tagStack = tagStack[:len(tagStack)-1] + } else { + err = fmt.Errorf("end group tag %d does not match begin group tag %d at pos %d", + protoFieldNumber(tag), protoFieldNumber(tagStack[len(tagStack)-1]), b.Pos) + } + } + if err != nil { + return err + } + } + return nil +} + +// skipVarint effiently skips a varint +func (b *BufferReader) SkipVarint() (err error) { + i := b.Pos + + if len(b.Buf)-i < 10 { + // Use DecodeVarintSlow() to check for buffer overflow, but ignore result + if _, err := b.DecodeVarintSlow(); err != nil { + return err + } + return nil + } + + if b.Buf[i] < 0x80 { + goto out + } + i++ + + if b.Buf[i] < 0x80 { + goto out + } + i++ + + if b.Buf[i] < 0x80 { + goto out + } + i++ + + if b.Buf[i] < 0x80 { + goto out + } + i++ + + if b.Buf[i] < 0x80 { + goto out + } + i++ + + if b.Buf[i] < 0x80 { + goto out + } + i++ + + if b.Buf[i] < 0x80 { + goto out + } + i++ + + if b.Buf[i] < 0x80 { + goto out + } + i++ + + if b.Buf[i] < 0x80 { + goto out + } + i++ + + if b.Buf[i] < 0x80 { + goto out + } + return errOverflow + +out: + b.Pos = i + 1 + return nil +} + +// skip skips the specified number of bytes +func (b *BufferReader) Skip(n int) (err error) { + if len(b.Buf) < b.Pos+n { + return io.ErrUnexpectedEOF + } + b.Pos += n + return +} + +// skipFixed64 skips a fixed64 +func (b *BufferReader) SkipFixed64() (err error) { + return b.Skip(8) +} + +// skipFixed32 skips a fixed32 +func (b *BufferReader) SkipFixed32() (err error) { + return b.Skip(4) +} + +// skipBytes skips a set of bytes +func (b *BufferReader) SkipBytes() (err error) { + n, err := b.DecodeVarint32() + if err != nil { + return err + } + return b.Skip(int(n)) +} + +// Done returns whether we are at the end of the protobuf +func (b *BufferReader) Done() bool { + return b.Pos == len(b.Buf) +} + +// Remaining returns how many bytes remain +func (b *BufferReader) Remaining() int { + return len(b.Buf) - b.Pos +} diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/protolazy/lazy.go b/go-controller/vendor/google.golang.org/protobuf/internal/protolazy/lazy.go new file mode 100644 index 0000000000..ff4d4834bb --- /dev/null +++ b/go-controller/vendor/google.golang.org/protobuf/internal/protolazy/lazy.go @@ -0,0 +1,359 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package protolazy contains internal data structures for lazy message decoding. +package protolazy + +import ( + "fmt" + "sort" + + "google.golang.org/protobuf/encoding/protowire" + piface "google.golang.org/protobuf/runtime/protoiface" +) + +// IndexEntry is the structure for an index of the fields in a message of a +// proto (not descending to sub-messages) +type IndexEntry struct { + FieldNum uint32 + // first byte of this tag/field + Start uint32 + // first byte after a contiguous sequence of bytes for this tag/field, which could + // include a single encoding of the field, or multiple encodings for the field + End uint32 + // True if this protobuf segment includes multiple encodings of the field + MultipleContiguous bool +} + +// XXX_lazyUnmarshalInfo has information about a particular lazily decoded message +// +// Deprecated: Do not use. This will be deleted in the near future. +type XXX_lazyUnmarshalInfo struct { + // Index of fields and their positions in the protobuf for this + // message. Make index be a pointer to a slice so it can be updated + // atomically. The index pointer is only set once (lazily when/if + // the index is first needed), and must always be SET and LOADED + // ATOMICALLY. + index *[]IndexEntry + // The protobuf associated with this lazily decoded message. It is + // only set during proto.Unmarshal(). It doesn't need to be set and + // loaded atomically, since any simultaneous set (Unmarshal) and read + // (during a get) would already be a race in the app code. + Protobuf []byte + // The flags present when Unmarshal was originally called for this particular message + unmarshalFlags piface.UnmarshalInputFlags +} + +// The Buffer and SetBuffer methods let v2/internal/impl interact with +// XXX_lazyUnmarshalInfo via an interface, to avoid an import cycle. + +// Buffer returns the lazy unmarshal buffer. +// +// Deprecated: Do not use. This will be deleted in the near future. +func (lazy *XXX_lazyUnmarshalInfo) Buffer() []byte { + return lazy.Protobuf +} + +// SetBuffer sets the lazy unmarshal buffer. +// +// Deprecated: Do not use. This will be deleted in the near future. +func (lazy *XXX_lazyUnmarshalInfo) SetBuffer(b []byte) { + lazy.Protobuf = b +} + +// SetUnmarshalFlags is called to set a copy of the original unmarshalInputFlags. +// The flags should reflect how Unmarshal was called. +func (lazy *XXX_lazyUnmarshalInfo) SetUnmarshalFlags(f piface.UnmarshalInputFlags) { + lazy.unmarshalFlags = f +} + +// UnmarshalFlags returns the original unmarshalInputFlags. +func (lazy *XXX_lazyUnmarshalInfo) UnmarshalFlags() piface.UnmarshalInputFlags { + return lazy.unmarshalFlags +} + +// AllowedPartial returns true if the user originally unmarshalled this message with +// AllowPartial set to true +func (lazy *XXX_lazyUnmarshalInfo) AllowedPartial() bool { + return (lazy.unmarshalFlags & piface.UnmarshalCheckRequired) == 0 +} + +func protoFieldNumber(tag uint32) uint32 { + return tag >> 3 +} + +// buildIndex builds an index of the specified protobuf, return the index +// array and an error. +func buildIndex(buf []byte) ([]IndexEntry, error) { + index := make([]IndexEntry, 0, 16) + var lastProtoFieldNum uint32 + var outOfOrder bool + + var r BufferReader = NewBufferReader(buf) + + for !r.Done() { + var tag uint32 + var err error + var curPos = r.Pos + // INLINED: tag, err = r.DecodeVarint32() + { + i := r.Pos + buf := r.Buf + + if i >= len(buf) { + return nil, errOutOfBounds + } else if buf[i] < 0x80 { + r.Pos++ + tag = uint32(buf[i]) + } else if r.Remaining() < 5 { + var v uint64 + v, err = r.DecodeVarintSlow() + tag = uint32(v) + } else { + var v uint32 + // we already checked the first byte + tag = uint32(buf[i]) & 127 + i++ + + v = uint32(buf[i]) + i++ + tag |= (v & 127) << 7 + if v < 128 { + goto done + } + + v = uint32(buf[i]) + i++ + tag |= (v & 127) << 14 + if v < 128 { + goto done + } + + v = uint32(buf[i]) + i++ + tag |= (v & 127) << 21 + if v < 128 { + goto done + } + + v = uint32(buf[i]) + i++ + tag |= (v & 127) << 28 + if v < 128 { + goto done + } + + return nil, errOutOfBounds + + done: + r.Pos = i + } + } + // DONE: tag, err = r.DecodeVarint32() + + fieldNum := protoFieldNumber(tag) + if fieldNum < lastProtoFieldNum { + outOfOrder = true + } + + // Skip the current value -- will skip over an entire group as well. + // INLINED: err = r.SkipValue(tag) + wireType := tag & 0x7 + switch protowire.Type(wireType) { + case protowire.VarintType: + // INLINED: err = r.SkipVarint() + i := r.Pos + + if len(r.Buf)-i < 10 { + // Use DecodeVarintSlow() to skip while + // checking for buffer overflow, but ignore result + _, err = r.DecodeVarintSlow() + goto out2 + } + if r.Buf[i] < 0x80 { + goto out + } + i++ + + if r.Buf[i] < 0x80 { + goto out + } + i++ + + if r.Buf[i] < 0x80 { + goto out + } + i++ + + if r.Buf[i] < 0x80 { + goto out + } + i++ + + if r.Buf[i] < 0x80 { + goto out + } + i++ + + if r.Buf[i] < 0x80 { + goto out + } + i++ + + if r.Buf[i] < 0x80 { + goto out + } + i++ + + if r.Buf[i] < 0x80 { + goto out + } + i++ + + if r.Buf[i] < 0x80 { + goto out + } + i++ + + if r.Buf[i] < 0x80 { + goto out + } + return nil, errOverflow + out: + r.Pos = i + 1 + // DONE: err = r.SkipVarint() + case protowire.Fixed64Type: + err = r.SkipFixed64() + case protowire.BytesType: + var n uint32 + n, err = r.DecodeVarint32() + if err == nil { + err = r.Skip(int(n)) + } + case protowire.StartGroupType: + err = r.SkipGroup(tag) + case protowire.Fixed32Type: + err = r.SkipFixed32() + default: + err = fmt.Errorf("Unexpected wire type (%d)", wireType) + } + // DONE: err = r.SkipValue(tag) + + out2: + if err != nil { + return nil, err + } + if fieldNum != lastProtoFieldNum { + index = append(index, IndexEntry{FieldNum: fieldNum, + Start: uint32(curPos), + End: uint32(r.Pos)}, + ) + } else { + index[len(index)-1].End = uint32(r.Pos) + index[len(index)-1].MultipleContiguous = true + } + lastProtoFieldNum = fieldNum + } + if outOfOrder { + sort.Slice(index, func(i, j int) bool { + return index[i].FieldNum < index[j].FieldNum || + (index[i].FieldNum == index[j].FieldNum && + index[i].Start < index[j].Start) + }) + } + return index, nil +} + +func (lazy *XXX_lazyUnmarshalInfo) SizeField(num uint32) (size int) { + start, end, found, _, multipleEntries := lazy.FindFieldInProto(num) + if multipleEntries != nil { + for _, entry := range multipleEntries { + size += int(entry.End - entry.Start) + } + return size + } + if !found { + return 0 + } + return int(end - start) +} + +func (lazy *XXX_lazyUnmarshalInfo) AppendField(b []byte, num uint32) ([]byte, bool) { + start, end, found, _, multipleEntries := lazy.FindFieldInProto(num) + if multipleEntries != nil { + for _, entry := range multipleEntries { + b = append(b, lazy.Protobuf[entry.Start:entry.End]...) + } + return b, true + } + if !found { + return nil, false + } + b = append(b, lazy.Protobuf[start:end]...) + return b, true +} + +func (lazy *XXX_lazyUnmarshalInfo) SetIndex(index []IndexEntry) { + atomicStoreIndex(&lazy.index, &index) +} + +// FindFieldInProto looks for field fieldNum in lazyUnmarshalInfo information +// (including protobuf), returns startOffset/endOffset/found. +func (lazy *XXX_lazyUnmarshalInfo) FindFieldInProto(fieldNum uint32) (start, end uint32, found, multipleContiguous bool, multipleEntries []IndexEntry) { + if lazy.Protobuf == nil { + // There is no backing protobuf for this message -- it was made from a builder + return 0, 0, false, false, nil + } + index := atomicLoadIndex(&lazy.index) + if index == nil { + r, err := buildIndex(lazy.Protobuf) + if err != nil { + panic(fmt.Sprintf("findFieldInfo: error building index when looking for field %d: %v", fieldNum, err)) + } + // lazy.index is a pointer to the slice returned by BuildIndex + index = &r + atomicStoreIndex(&lazy.index, index) + } + return lookupField(index, fieldNum) +} + +// lookupField returns the offset at which the indicated field starts using +// the index, offset immediately after field ends (including all instances of +// a repeated field), and bools indicating if field was found and if there +// are multiple encodings of the field in the byte range. +// +// To hande the uncommon case where there are repeated encodings for the same +// field which are not consecutive in the protobuf (so we need to returns +// multiple start/end offsets), we also return a slice multipleEntries. If +// multipleEntries is non-nil, then multiple entries were found, and the +// values in the slice should be used, rather than start/end/found. +func lookupField(indexp *[]IndexEntry, fieldNum uint32) (start, end uint32, found bool, multipleContiguous bool, multipleEntries []IndexEntry) { + // The pointer indexp to the index was already loaded atomically. + // The slice is uniquely associated with the pointer, so it doesn't + // need to be loaded atomically. + index := *indexp + for i, entry := range index { + if fieldNum == entry.FieldNum { + if i < len(index)-1 && entry.FieldNum == index[i+1].FieldNum { + // Handle the uncommon case where there are + // repeated entries for the same field which + // are not contiguous in the protobuf. + multiple := make([]IndexEntry, 1, 2) + multiple[0] = IndexEntry{fieldNum, entry.Start, entry.End, entry.MultipleContiguous} + i++ + for i < len(index) && index[i].FieldNum == fieldNum { + multiple = append(multiple, IndexEntry{fieldNum, index[i].Start, index[i].End, index[i].MultipleContiguous}) + i++ + } + return 0, 0, false, false, multiple + + } + return entry.Start, entry.End, true, entry.MultipleContiguous, nil + } + if fieldNum < entry.FieldNum { + return 0, 0, false, false, nil + } + } + return 0, 0, false, false, nil +} diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/protolazy/pointer_unsafe.go b/go-controller/vendor/google.golang.org/protobuf/internal/protolazy/pointer_unsafe.go new file mode 100644 index 0000000000..dc2a64ca64 --- /dev/null +++ b/go-controller/vendor/google.golang.org/protobuf/internal/protolazy/pointer_unsafe.go @@ -0,0 +1,17 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package protolazy + +import ( + "sync/atomic" + "unsafe" +) + +func atomicLoadIndex(p **[]IndexEntry) *[]IndexEntry { + return (*[]IndexEntry)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p)))) +} +func atomicStoreIndex(p **[]IndexEntry, v *[]IndexEntry) { + atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v)) +} diff --git a/go-controller/vendor/google.golang.org/protobuf/internal/version/version.go b/go-controller/vendor/google.golang.org/protobuf/internal/version/version.go index fb8e15e8da..01efc33030 100644 --- a/go-controller/vendor/google.golang.org/protobuf/internal/version/version.go +++ b/go-controller/vendor/google.golang.org/protobuf/internal/version/version.go @@ -51,8 +51,8 @@ import ( // 10. Send out the CL for review and submit it. const ( Major = 1 - Minor = 35 - Patch = 1 + Minor = 36 + Patch = 5 PreRelease = "" ) diff --git a/go-controller/vendor/google.golang.org/protobuf/proto/decode.go b/go-controller/vendor/google.golang.org/protobuf/proto/decode.go index d75a6534c1..4cbf1aeaf7 100644 --- a/go-controller/vendor/google.golang.org/protobuf/proto/decode.go +++ b/go-controller/vendor/google.golang.org/protobuf/proto/decode.go @@ -8,7 +8,6 @@ import ( "google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/internal/encoding/messageset" "google.golang.org/protobuf/internal/errors" - "google.golang.org/protobuf/internal/flags" "google.golang.org/protobuf/internal/genid" "google.golang.org/protobuf/internal/pragma" "google.golang.org/protobuf/reflect/protoreflect" @@ -47,6 +46,12 @@ type UnmarshalOptions struct { // RecursionLimit limits how deeply messages may be nested. // If zero, a default limit is applied. RecursionLimit int + + // + // NoLazyDecoding turns off lazy decoding, which otherwise is enabled by + // default. Lazy decoding only affects submessages (annotated with [lazy = + // true] in the .proto file) within messages that use the Opaque API. + NoLazyDecoding bool } // Unmarshal parses the wire-format message in b and places the result in m. @@ -104,6 +109,16 @@ func (o UnmarshalOptions) unmarshal(b []byte, m protoreflect.Message) (out proto if o.DiscardUnknown { in.Flags |= protoiface.UnmarshalDiscardUnknown } + + if !allowPartial { + // This does not affect how current unmarshal functions work, it just allows them + // to record this for lazy the decoding case. + in.Flags |= protoiface.UnmarshalCheckRequired + } + if o.NoLazyDecoding { + in.Flags |= protoiface.UnmarshalNoLazyDecoding + } + out, err = methods.Unmarshal(in) } else { o.RecursionLimit-- @@ -156,10 +171,6 @@ func (o UnmarshalOptions) unmarshalMessageSlow(b []byte, m protoreflect.Message) var err error if fd == nil { err = errUnknown - } else if flags.ProtoLegacy { - if fd.IsWeak() && fd.Message().IsPlaceholder() { - err = errUnknown // weak referent is not linked in - } } // Parse the field value. diff --git a/go-controller/vendor/google.golang.org/protobuf/proto/encode.go b/go-controller/vendor/google.golang.org/protobuf/proto/encode.go index 1f847bcc35..f0473c5869 100644 --- a/go-controller/vendor/google.golang.org/protobuf/proto/encode.go +++ b/go-controller/vendor/google.golang.org/protobuf/proto/encode.go @@ -63,7 +63,8 @@ type MarshalOptions struct { // options (except for UseCachedSize itself). // // 2. The message and all its submessages have not changed in any - // way since the Size call. + // way since the Size call. For lazily decoded messages, accessing + // a message results in decoding the message, which is a change. // // If either of these invariants is violated, // the results are undefined and may include panics or corrupted output. diff --git a/go-controller/vendor/google.golang.org/protobuf/proto/size.go b/go-controller/vendor/google.golang.org/protobuf/proto/size.go index 052fb5ae31..c8675806c6 100644 --- a/go-controller/vendor/google.golang.org/protobuf/proto/size.go +++ b/go-controller/vendor/google.golang.org/protobuf/proto/size.go @@ -12,11 +12,19 @@ import ( ) // Size returns the size in bytes of the wire-format encoding of m. +// +// Note that Size might return more bytes than Marshal will write in the case of +// lazily decoded messages that arrive in non-minimal wire format: see +// https://protobuf.dev/reference/go/size/ for more details. func Size(m Message) int { return MarshalOptions{}.Size(m) } // Size returns the size in bytes of the wire-format encoding of m. +// +// Note that Size might return more bytes than Marshal will write in the case of +// lazily decoded messages that arrive in non-minimal wire format: see +// https://protobuf.dev/reference/go/size/ for more details. func (o MarshalOptions) Size(m Message) int { // Treat a nil message interface as an empty message; nothing to output. if m == nil { diff --git a/go-controller/vendor/google.golang.org/protobuf/proto/wrapperopaque.go b/go-controller/vendor/google.golang.org/protobuf/proto/wrapperopaque.go new file mode 100644 index 0000000000..267fd0f1f6 --- /dev/null +++ b/go-controller/vendor/google.golang.org/protobuf/proto/wrapperopaque.go @@ -0,0 +1,80 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package proto + +// ValueOrNil returns nil if has is false, or a pointer to a new variable +// containing the value returned by the specified getter. +// +// This function is similar to the wrappers (proto.Int32(), proto.String(), +// etc.), but is generic (works for any field type) and works with the hasser +// and getter of a field, as opposed to a value. +// +// This is convenient when populating builder fields. +// +// Example: +// +// hop := attr.GetDirectHop() +// injectedRoute := ripb.InjectedRoute_builder{ +// Prefixes: route.GetPrefixes(), +// NextHop: proto.ValueOrNil(hop.HasAddress(), hop.GetAddress), +// } +func ValueOrNil[T any](has bool, getter func() T) *T { + if !has { + return nil + } + v := getter() + return &v +} + +// ValueOrDefault returns the protobuf message val if val is not nil, otherwise +// it returns a pointer to an empty val message. +// +// This function allows for translating code from the old Open Struct API to the +// new Opaque API. +// +// The old Open Struct API represented oneof fields with a wrapper struct: +// +// var signedImg *accountpb.SignedImage +// profile := &accountpb.Profile{ +// // The Avatar oneof will be set, with an empty SignedImage. +// Avatar: &accountpb.Profile_SignedImage{signedImg}, +// } +// +// The new Opaque API treats oneof fields like regular fields, there are no more +// wrapper structs: +// +// var signedImg *accountpb.SignedImage +// profile := &accountpb.Profile{} +// profile.SetSignedImage(signedImg) +// +// For convenience, the Opaque API also offers Builders, which allow for a +// direct translation of struct initialization. However, because Builders use +// nilness to represent field presence (but there is no non-nil wrapper struct +// anymore), Builders cannot distinguish between an unset oneof and a set oneof +// with nil message. The above code would need to be translated with help of the +// ValueOrDefault function to retain the same behavior: +// +// var signedImg *accountpb.SignedImage +// return &accountpb.Profile_builder{ +// SignedImage: proto.ValueOrDefault(signedImg), +// }.Build() +func ValueOrDefault[T interface { + *P + Message +}, P any](val T) T { + if val == nil { + return T(new(P)) + } + return val +} + +// ValueOrDefaultBytes is like ValueOrDefault but for working with fields of +// type []byte. +func ValueOrDefaultBytes(val []byte) []byte { + if val == nil { + return []byte{} + } + return val +} diff --git a/go-controller/vendor/google.golang.org/protobuf/reflect/protodesc/desc.go b/go-controller/vendor/google.golang.org/protobuf/reflect/protodesc/desc.go deleted file mode 100644 index 8fbecb4f58..0000000000 --- a/go-controller/vendor/google.golang.org/protobuf/reflect/protodesc/desc.go +++ /dev/null @@ -1,286 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package protodesc provides functionality for converting -// FileDescriptorProto messages to/from [protoreflect.FileDescriptor] values. -// -// The google.protobuf.FileDescriptorProto is a protobuf message that describes -// the type information for a .proto file in a form that is easily serializable. -// The [protoreflect.FileDescriptor] is a more structured representation of -// the FileDescriptorProto message where references and remote dependencies -// can be directly followed. -package protodesc - -import ( - "google.golang.org/protobuf/internal/editionssupport" - "google.golang.org/protobuf/internal/errors" - "google.golang.org/protobuf/internal/filedesc" - "google.golang.org/protobuf/internal/pragma" - "google.golang.org/protobuf/internal/strs" - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/reflect/protoregistry" - - "google.golang.org/protobuf/types/descriptorpb" -) - -// Resolver is the resolver used by [NewFile] to resolve dependencies. -// The enums and messages provided must belong to some parent file, -// which is also registered. -// -// It is implemented by [protoregistry.Files]. -type Resolver interface { - FindFileByPath(string) (protoreflect.FileDescriptor, error) - FindDescriptorByName(protoreflect.FullName) (protoreflect.Descriptor, error) -} - -// FileOptions configures the construction of file descriptors. -type FileOptions struct { - pragma.NoUnkeyedLiterals - - // AllowUnresolvable configures New to permissively allow unresolvable - // file, enum, or message dependencies. Unresolved dependencies are replaced - // by placeholder equivalents. - // - // The following dependencies may be left unresolved: - // • Resolving an imported file. - // • Resolving the type for a message field or extension field. - // If the kind of the field is unknown, then a placeholder is used for both - // the Enum and Message accessors on the protoreflect.FieldDescriptor. - // • Resolving an enum value set as the default for an optional enum field. - // If unresolvable, the protoreflect.FieldDescriptor.Default is set to the - // first value in the associated enum (or zero if the also enum dependency - // is also unresolvable). The protoreflect.FieldDescriptor.DefaultEnumValue - // is populated with a placeholder. - // • Resolving the extended message type for an extension field. - // • Resolving the input or output message type for a service method. - // - // If the unresolved dependency uses a relative name, - // then the placeholder will contain an invalid FullName with a "*." prefix, - // indicating that the starting prefix of the full name is unknown. - AllowUnresolvable bool -} - -// NewFile creates a new [protoreflect.FileDescriptor] from the provided -// file descriptor message. See [FileOptions.New] for more information. -func NewFile(fd *descriptorpb.FileDescriptorProto, r Resolver) (protoreflect.FileDescriptor, error) { - return FileOptions{}.New(fd, r) -} - -// NewFiles creates a new [protoregistry.Files] from the provided -// FileDescriptorSet message. See [FileOptions.NewFiles] for more information. -func NewFiles(fd *descriptorpb.FileDescriptorSet) (*protoregistry.Files, error) { - return FileOptions{}.NewFiles(fd) -} - -// New creates a new [protoreflect.FileDescriptor] from the provided -// file descriptor message. The file must represent a valid proto file according -// to protobuf semantics. The returned descriptor is a deep copy of the input. -// -// Any imported files, enum types, or message types referenced in the file are -// resolved using the provided registry. When looking up an import file path, -// the path must be unique. The newly created file descriptor is not registered -// back into the provided file registry. -func (o FileOptions) New(fd *descriptorpb.FileDescriptorProto, r Resolver) (protoreflect.FileDescriptor, error) { - if r == nil { - r = (*protoregistry.Files)(nil) // empty resolver - } - - // Handle the file descriptor content. - f := &filedesc.File{L2: &filedesc.FileL2{}} - switch fd.GetSyntax() { - case "proto2", "": - f.L1.Syntax = protoreflect.Proto2 - f.L1.Edition = filedesc.EditionProto2 - case "proto3": - f.L1.Syntax = protoreflect.Proto3 - f.L1.Edition = filedesc.EditionProto3 - case "editions": - f.L1.Syntax = protoreflect.Editions - f.L1.Edition = fromEditionProto(fd.GetEdition()) - default: - return nil, errors.New("invalid syntax: %q", fd.GetSyntax()) - } - if f.L1.Syntax == protoreflect.Editions && (fd.GetEdition() < editionssupport.Minimum || fd.GetEdition() > editionssupport.Maximum) { - return nil, errors.New("use of edition %v not yet supported by the Go Protobuf runtime", fd.GetEdition()) - } - f.L1.Path = fd.GetName() - if f.L1.Path == "" { - return nil, errors.New("file path must be populated") - } - f.L1.Package = protoreflect.FullName(fd.GetPackage()) - if !f.L1.Package.IsValid() && f.L1.Package != "" { - return nil, errors.New("invalid package: %q", f.L1.Package) - } - if opts := fd.GetOptions(); opts != nil { - opts = proto.Clone(opts).(*descriptorpb.FileOptions) - f.L2.Options = func() protoreflect.ProtoMessage { return opts } - } - initFileDescFromFeatureSet(f, fd.GetOptions().GetFeatures()) - - f.L2.Imports = make(filedesc.FileImports, len(fd.GetDependency())) - for _, i := range fd.GetPublicDependency() { - if !(0 <= i && int(i) < len(f.L2.Imports)) || f.L2.Imports[i].IsPublic { - return nil, errors.New("invalid or duplicate public import index: %d", i) - } - f.L2.Imports[i].IsPublic = true - } - for _, i := range fd.GetWeakDependency() { - if !(0 <= i && int(i) < len(f.L2.Imports)) || f.L2.Imports[i].IsWeak { - return nil, errors.New("invalid or duplicate weak import index: %d", i) - } - f.L2.Imports[i].IsWeak = true - } - imps := importSet{f.Path(): true} - for i, path := range fd.GetDependency() { - imp := &f.L2.Imports[i] - f, err := r.FindFileByPath(path) - if err == protoregistry.NotFound && (o.AllowUnresolvable || imp.IsWeak) { - f = filedesc.PlaceholderFile(path) - } else if err != nil { - return nil, errors.New("could not resolve import %q: %v", path, err) - } - imp.FileDescriptor = f - - if imps[imp.Path()] { - return nil, errors.New("already imported %q", path) - } - imps[imp.Path()] = true - } - for i := range fd.GetDependency() { - imp := &f.L2.Imports[i] - imps.importPublic(imp.Imports()) - } - - // Handle source locations. - f.L2.Locations.File = f - for _, loc := range fd.GetSourceCodeInfo().GetLocation() { - var l protoreflect.SourceLocation - // TODO: Validate that the path points to an actual declaration? - l.Path = protoreflect.SourcePath(loc.GetPath()) - s := loc.GetSpan() - switch len(s) { - case 3: - l.StartLine, l.StartColumn, l.EndLine, l.EndColumn = int(s[0]), int(s[1]), int(s[0]), int(s[2]) - case 4: - l.StartLine, l.StartColumn, l.EndLine, l.EndColumn = int(s[0]), int(s[1]), int(s[2]), int(s[3]) - default: - return nil, errors.New("invalid span: %v", s) - } - // TODO: Validate that the span information is sensible? - // See https://github.com/protocolbuffers/protobuf/issues/6378. - if false && (l.EndLine < l.StartLine || l.StartLine < 0 || l.StartColumn < 0 || l.EndColumn < 0 || - (l.StartLine == l.EndLine && l.EndColumn <= l.StartColumn)) { - return nil, errors.New("invalid span: %v", s) - } - l.LeadingDetachedComments = loc.GetLeadingDetachedComments() - l.LeadingComments = loc.GetLeadingComments() - l.TrailingComments = loc.GetTrailingComments() - f.L2.Locations.List = append(f.L2.Locations.List, l) - } - - // Step 1: Allocate and derive the names for all declarations. - // This copies all fields from the descriptor proto except: - // google.protobuf.FieldDescriptorProto.type_name - // google.protobuf.FieldDescriptorProto.default_value - // google.protobuf.FieldDescriptorProto.oneof_index - // google.protobuf.FieldDescriptorProto.extendee - // google.protobuf.MethodDescriptorProto.input - // google.protobuf.MethodDescriptorProto.output - var err error - sb := new(strs.Builder) - r1 := make(descsByName) - if f.L1.Enums.List, err = r1.initEnumDeclarations(fd.GetEnumType(), f, sb); err != nil { - return nil, err - } - if f.L1.Messages.List, err = r1.initMessagesDeclarations(fd.GetMessageType(), f, sb); err != nil { - return nil, err - } - if f.L1.Extensions.List, err = r1.initExtensionDeclarations(fd.GetExtension(), f, sb); err != nil { - return nil, err - } - if f.L1.Services.List, err = r1.initServiceDeclarations(fd.GetService(), f, sb); err != nil { - return nil, err - } - - // Step 2: Resolve every dependency reference not handled by step 1. - r2 := &resolver{local: r1, remote: r, imports: imps, allowUnresolvable: o.AllowUnresolvable} - if err := r2.resolveMessageDependencies(f.L1.Messages.List, fd.GetMessageType()); err != nil { - return nil, err - } - if err := r2.resolveExtensionDependencies(f.L1.Extensions.List, fd.GetExtension()); err != nil { - return nil, err - } - if err := r2.resolveServiceDependencies(f.L1.Services.List, fd.GetService()); err != nil { - return nil, err - } - - // Step 3: Validate every enum, message, and extension declaration. - if err := validateEnumDeclarations(f.L1.Enums.List, fd.GetEnumType()); err != nil { - return nil, err - } - if err := validateMessageDeclarations(f, f.L1.Messages.List, fd.GetMessageType()); err != nil { - return nil, err - } - if err := validateExtensionDeclarations(f, f.L1.Extensions.List, fd.GetExtension()); err != nil { - return nil, err - } - - return f, nil -} - -type importSet map[string]bool - -func (is importSet) importPublic(imps protoreflect.FileImports) { - for i := 0; i < imps.Len(); i++ { - if imp := imps.Get(i); imp.IsPublic { - is[imp.Path()] = true - is.importPublic(imp.Imports()) - } - } -} - -// NewFiles creates a new [protoregistry.Files] from the provided -// FileDescriptorSet message. The descriptor set must include only -// valid files according to protobuf semantics. The returned descriptors -// are a deep copy of the input. -func (o FileOptions) NewFiles(fds *descriptorpb.FileDescriptorSet) (*protoregistry.Files, error) { - files := make(map[string]*descriptorpb.FileDescriptorProto) - for _, fd := range fds.File { - if _, ok := files[fd.GetName()]; ok { - return nil, errors.New("file appears multiple times: %q", fd.GetName()) - } - files[fd.GetName()] = fd - } - r := &protoregistry.Files{} - for _, fd := range files { - if err := o.addFileDeps(r, fd, files); err != nil { - return nil, err - } - } - return r, nil -} -func (o FileOptions) addFileDeps(r *protoregistry.Files, fd *descriptorpb.FileDescriptorProto, files map[string]*descriptorpb.FileDescriptorProto) error { - // Set the entry to nil while descending into a file's dependencies to detect cycles. - files[fd.GetName()] = nil - for _, dep := range fd.Dependency { - depfd, ok := files[dep] - if depfd == nil { - if ok { - return errors.New("import cycle in file: %q", dep) - } - continue - } - if err := o.addFileDeps(r, depfd, files); err != nil { - return err - } - } - // Delete the entry once dependencies are processed. - delete(files, fd.GetName()) - f, err := o.New(fd, r) - if err != nil { - return err - } - return r.RegisterFile(f) -} diff --git a/go-controller/vendor/google.golang.org/protobuf/reflect/protodesc/desc_init.go b/go-controller/vendor/google.golang.org/protobuf/reflect/protodesc/desc_init.go deleted file mode 100644 index ebcb4a8ab1..0000000000 --- a/go-controller/vendor/google.golang.org/protobuf/reflect/protodesc/desc_init.go +++ /dev/null @@ -1,289 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package protodesc - -import ( - "google.golang.org/protobuf/internal/errors" - "google.golang.org/protobuf/internal/filedesc" - "google.golang.org/protobuf/internal/strs" - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/reflect/protoreflect" - - "google.golang.org/protobuf/types/descriptorpb" -) - -type descsByName map[protoreflect.FullName]protoreflect.Descriptor - -func (r descsByName) initEnumDeclarations(eds []*descriptorpb.EnumDescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (es []filedesc.Enum, err error) { - es = make([]filedesc.Enum, len(eds)) // allocate up-front to ensure stable pointers - for i, ed := range eds { - e := &es[i] - e.L2 = new(filedesc.EnumL2) - if e.L0, err = r.makeBase(e, parent, ed.GetName(), i, sb); err != nil { - return nil, err - } - if opts := ed.GetOptions(); opts != nil { - opts = proto.Clone(opts).(*descriptorpb.EnumOptions) - e.L2.Options = func() protoreflect.ProtoMessage { return opts } - } - e.L1.EditionFeatures = mergeEditionFeatures(parent, ed.GetOptions().GetFeatures()) - for _, s := range ed.GetReservedName() { - e.L2.ReservedNames.List = append(e.L2.ReservedNames.List, protoreflect.Name(s)) - } - for _, rr := range ed.GetReservedRange() { - e.L2.ReservedRanges.List = append(e.L2.ReservedRanges.List, [2]protoreflect.EnumNumber{ - protoreflect.EnumNumber(rr.GetStart()), - protoreflect.EnumNumber(rr.GetEnd()), - }) - } - if e.L2.Values.List, err = r.initEnumValuesFromDescriptorProto(ed.GetValue(), e, sb); err != nil { - return nil, err - } - } - return es, nil -} - -func (r descsByName) initEnumValuesFromDescriptorProto(vds []*descriptorpb.EnumValueDescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (vs []filedesc.EnumValue, err error) { - vs = make([]filedesc.EnumValue, len(vds)) // allocate up-front to ensure stable pointers - for i, vd := range vds { - v := &vs[i] - if v.L0, err = r.makeBase(v, parent, vd.GetName(), i, sb); err != nil { - return nil, err - } - if opts := vd.GetOptions(); opts != nil { - opts = proto.Clone(opts).(*descriptorpb.EnumValueOptions) - v.L1.Options = func() protoreflect.ProtoMessage { return opts } - } - v.L1.Number = protoreflect.EnumNumber(vd.GetNumber()) - } - return vs, nil -} - -func (r descsByName) initMessagesDeclarations(mds []*descriptorpb.DescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (ms []filedesc.Message, err error) { - ms = make([]filedesc.Message, len(mds)) // allocate up-front to ensure stable pointers - for i, md := range mds { - m := &ms[i] - m.L2 = new(filedesc.MessageL2) - if m.L0, err = r.makeBase(m, parent, md.GetName(), i, sb); err != nil { - return nil, err - } - m.L1.EditionFeatures = mergeEditionFeatures(parent, md.GetOptions().GetFeatures()) - if opts := md.GetOptions(); opts != nil { - opts = proto.Clone(opts).(*descriptorpb.MessageOptions) - m.L2.Options = func() protoreflect.ProtoMessage { return opts } - m.L1.IsMapEntry = opts.GetMapEntry() - m.L1.IsMessageSet = opts.GetMessageSetWireFormat() - } - for _, s := range md.GetReservedName() { - m.L2.ReservedNames.List = append(m.L2.ReservedNames.List, protoreflect.Name(s)) - } - for _, rr := range md.GetReservedRange() { - m.L2.ReservedRanges.List = append(m.L2.ReservedRanges.List, [2]protoreflect.FieldNumber{ - protoreflect.FieldNumber(rr.GetStart()), - protoreflect.FieldNumber(rr.GetEnd()), - }) - } - for _, xr := range md.GetExtensionRange() { - m.L2.ExtensionRanges.List = append(m.L2.ExtensionRanges.List, [2]protoreflect.FieldNumber{ - protoreflect.FieldNumber(xr.GetStart()), - protoreflect.FieldNumber(xr.GetEnd()), - }) - var optsFunc func() protoreflect.ProtoMessage - if opts := xr.GetOptions(); opts != nil { - opts = proto.Clone(opts).(*descriptorpb.ExtensionRangeOptions) - optsFunc = func() protoreflect.ProtoMessage { return opts } - } - m.L2.ExtensionRangeOptions = append(m.L2.ExtensionRangeOptions, optsFunc) - } - if m.L2.Fields.List, err = r.initFieldsFromDescriptorProto(md.GetField(), m, sb); err != nil { - return nil, err - } - if m.L2.Oneofs.List, err = r.initOneofsFromDescriptorProto(md.GetOneofDecl(), m, sb); err != nil { - return nil, err - } - if m.L1.Enums.List, err = r.initEnumDeclarations(md.GetEnumType(), m, sb); err != nil { - return nil, err - } - if m.L1.Messages.List, err = r.initMessagesDeclarations(md.GetNestedType(), m, sb); err != nil { - return nil, err - } - if m.L1.Extensions.List, err = r.initExtensionDeclarations(md.GetExtension(), m, sb); err != nil { - return nil, err - } - } - return ms, nil -} - -// canBePacked returns whether the field can use packed encoding: -// https://protobuf.dev/programming-guides/encoding/#packed -func canBePacked(fd *descriptorpb.FieldDescriptorProto) bool { - if fd.GetLabel() != descriptorpb.FieldDescriptorProto_LABEL_REPEATED { - return false // not a repeated field - } - - switch protoreflect.Kind(fd.GetType()) { - case protoreflect.MessageKind, protoreflect.GroupKind: - return false // not a scalar type field - - case protoreflect.StringKind, protoreflect.BytesKind: - // string and bytes can explicitly not be declared as packed, - // see https://protobuf.dev/programming-guides/encoding/#packed - return false - - default: - return true - } -} - -func (r descsByName) initFieldsFromDescriptorProto(fds []*descriptorpb.FieldDescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (fs []filedesc.Field, err error) { - fs = make([]filedesc.Field, len(fds)) // allocate up-front to ensure stable pointers - for i, fd := range fds { - f := &fs[i] - if f.L0, err = r.makeBase(f, parent, fd.GetName(), i, sb); err != nil { - return nil, err - } - f.L1.EditionFeatures = mergeEditionFeatures(parent, fd.GetOptions().GetFeatures()) - f.L1.IsProto3Optional = fd.GetProto3Optional() - if opts := fd.GetOptions(); opts != nil { - opts = proto.Clone(opts).(*descriptorpb.FieldOptions) - f.L1.Options = func() protoreflect.ProtoMessage { return opts } - f.L1.IsWeak = opts.GetWeak() - f.L1.IsLazy = opts.GetLazy() - if opts.Packed != nil { - f.L1.EditionFeatures.IsPacked = opts.GetPacked() - } - } - f.L1.Number = protoreflect.FieldNumber(fd.GetNumber()) - f.L1.Cardinality = protoreflect.Cardinality(fd.GetLabel()) - if fd.Type != nil { - f.L1.Kind = protoreflect.Kind(fd.GetType()) - } - if fd.JsonName != nil { - f.L1.StringName.InitJSON(fd.GetJsonName()) - } - - if f.L1.EditionFeatures.IsLegacyRequired { - f.L1.Cardinality = protoreflect.Required - } - - if f.L1.Kind == protoreflect.MessageKind && f.L1.EditionFeatures.IsDelimitedEncoded { - f.L1.Kind = protoreflect.GroupKind - } - } - return fs, nil -} - -func (r descsByName) initOneofsFromDescriptorProto(ods []*descriptorpb.OneofDescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (os []filedesc.Oneof, err error) { - os = make([]filedesc.Oneof, len(ods)) // allocate up-front to ensure stable pointers - for i, od := range ods { - o := &os[i] - if o.L0, err = r.makeBase(o, parent, od.GetName(), i, sb); err != nil { - return nil, err - } - o.L1.EditionFeatures = mergeEditionFeatures(parent, od.GetOptions().GetFeatures()) - if opts := od.GetOptions(); opts != nil { - opts = proto.Clone(opts).(*descriptorpb.OneofOptions) - o.L1.Options = func() protoreflect.ProtoMessage { return opts } - } - } - return os, nil -} - -func (r descsByName) initExtensionDeclarations(xds []*descriptorpb.FieldDescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (xs []filedesc.Extension, err error) { - xs = make([]filedesc.Extension, len(xds)) // allocate up-front to ensure stable pointers - for i, xd := range xds { - x := &xs[i] - x.L2 = new(filedesc.ExtensionL2) - if x.L0, err = r.makeBase(x, parent, xd.GetName(), i, sb); err != nil { - return nil, err - } - x.L1.EditionFeatures = mergeEditionFeatures(parent, xd.GetOptions().GetFeatures()) - if opts := xd.GetOptions(); opts != nil { - opts = proto.Clone(opts).(*descriptorpb.FieldOptions) - x.L2.Options = func() protoreflect.ProtoMessage { return opts } - if opts.Packed != nil { - x.L1.EditionFeatures.IsPacked = opts.GetPacked() - } - } - x.L1.Number = protoreflect.FieldNumber(xd.GetNumber()) - x.L1.Cardinality = protoreflect.Cardinality(xd.GetLabel()) - if xd.Type != nil { - x.L1.Kind = protoreflect.Kind(xd.GetType()) - } - if xd.JsonName != nil { - x.L2.StringName.InitJSON(xd.GetJsonName()) - } - if x.L1.Kind == protoreflect.MessageKind && x.L1.EditionFeatures.IsDelimitedEncoded { - x.L1.Kind = protoreflect.GroupKind - } - } - return xs, nil -} - -func (r descsByName) initServiceDeclarations(sds []*descriptorpb.ServiceDescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (ss []filedesc.Service, err error) { - ss = make([]filedesc.Service, len(sds)) // allocate up-front to ensure stable pointers - for i, sd := range sds { - s := &ss[i] - s.L2 = new(filedesc.ServiceL2) - if s.L0, err = r.makeBase(s, parent, sd.GetName(), i, sb); err != nil { - return nil, err - } - if opts := sd.GetOptions(); opts != nil { - opts = proto.Clone(opts).(*descriptorpb.ServiceOptions) - s.L2.Options = func() protoreflect.ProtoMessage { return opts } - } - if s.L2.Methods.List, err = r.initMethodsFromDescriptorProto(sd.GetMethod(), s, sb); err != nil { - return nil, err - } - } - return ss, nil -} - -func (r descsByName) initMethodsFromDescriptorProto(mds []*descriptorpb.MethodDescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (ms []filedesc.Method, err error) { - ms = make([]filedesc.Method, len(mds)) // allocate up-front to ensure stable pointers - for i, md := range mds { - m := &ms[i] - if m.L0, err = r.makeBase(m, parent, md.GetName(), i, sb); err != nil { - return nil, err - } - if opts := md.GetOptions(); opts != nil { - opts = proto.Clone(opts).(*descriptorpb.MethodOptions) - m.L1.Options = func() protoreflect.ProtoMessage { return opts } - } - m.L1.IsStreamingClient = md.GetClientStreaming() - m.L1.IsStreamingServer = md.GetServerStreaming() - } - return ms, nil -} - -func (r descsByName) makeBase(child, parent protoreflect.Descriptor, name string, idx int, sb *strs.Builder) (filedesc.BaseL0, error) { - if !protoreflect.Name(name).IsValid() { - return filedesc.BaseL0{}, errors.New("descriptor %q has an invalid nested name: %q", parent.FullName(), name) - } - - // Derive the full name of the child. - // Note that enum values are a sibling to the enum parent in the namespace. - var fullName protoreflect.FullName - if _, ok := parent.(protoreflect.EnumDescriptor); ok { - fullName = sb.AppendFullName(parent.FullName().Parent(), protoreflect.Name(name)) - } else { - fullName = sb.AppendFullName(parent.FullName(), protoreflect.Name(name)) - } - if _, ok := r[fullName]; ok { - return filedesc.BaseL0{}, errors.New("descriptor %q already declared", fullName) - } - r[fullName] = child - - // TODO: Verify that the full name does not already exist in the resolver? - // This is not as critical since most usages of NewFile will register - // the created file back into the registry, which will perform this check. - - return filedesc.BaseL0{ - FullName: fullName, - ParentFile: parent.ParentFile().(*filedesc.File), - Parent: parent, - Index: idx, - }, nil -} diff --git a/go-controller/vendor/google.golang.org/protobuf/reflect/protodesc/desc_resolve.go b/go-controller/vendor/google.golang.org/protobuf/reflect/protodesc/desc_resolve.go deleted file mode 100644 index f3cebab29c..0000000000 --- a/go-controller/vendor/google.golang.org/protobuf/reflect/protodesc/desc_resolve.go +++ /dev/null @@ -1,291 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package protodesc - -import ( - "google.golang.org/protobuf/internal/encoding/defval" - "google.golang.org/protobuf/internal/errors" - "google.golang.org/protobuf/internal/filedesc" - "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/reflect/protoregistry" - - "google.golang.org/protobuf/types/descriptorpb" -) - -// resolver is a wrapper around a local registry of declarations within the file -// and the remote resolver. The remote resolver is restricted to only return -// descriptors that have been imported. -type resolver struct { - local descsByName - remote Resolver - imports importSet - - allowUnresolvable bool -} - -func (r *resolver) resolveMessageDependencies(ms []filedesc.Message, mds []*descriptorpb.DescriptorProto) (err error) { - for i, md := range mds { - m := &ms[i] - for j, fd := range md.GetField() { - f := &m.L2.Fields.List[j] - if f.L1.Cardinality == protoreflect.Required { - m.L2.RequiredNumbers.List = append(m.L2.RequiredNumbers.List, f.L1.Number) - } - if fd.OneofIndex != nil { - k := int(fd.GetOneofIndex()) - if !(0 <= k && k < len(md.GetOneofDecl())) { - return errors.New("message field %q has an invalid oneof index: %d", f.FullName(), k) - } - o := &m.L2.Oneofs.List[k] - f.L1.ContainingOneof = o - o.L1.Fields.List = append(o.L1.Fields.List, f) - } - - if f.L1.Kind, f.L1.Enum, f.L1.Message, err = r.findTarget(f.Kind(), f.Parent().FullName(), partialName(fd.GetTypeName()), f.IsWeak()); err != nil { - return errors.New("message field %q cannot resolve type: %v", f.FullName(), err) - } - if f.L1.Kind == protoreflect.GroupKind && (f.IsMap() || f.IsMapEntry()) { - // A map field might inherit delimited encoding from a file-wide default feature. - // But maps never actually use delimited encoding. (At least for now...) - f.L1.Kind = protoreflect.MessageKind - } - if fd.DefaultValue != nil { - v, ev, err := unmarshalDefault(fd.GetDefaultValue(), f, r.allowUnresolvable) - if err != nil { - return errors.New("message field %q has invalid default: %v", f.FullName(), err) - } - f.L1.Default = filedesc.DefaultValue(v, ev) - } - } - - if err := r.resolveMessageDependencies(m.L1.Messages.List, md.GetNestedType()); err != nil { - return err - } - if err := r.resolveExtensionDependencies(m.L1.Extensions.List, md.GetExtension()); err != nil { - return err - } - } - return nil -} - -func (r *resolver) resolveExtensionDependencies(xs []filedesc.Extension, xds []*descriptorpb.FieldDescriptorProto) (err error) { - for i, xd := range xds { - x := &xs[i] - if x.L1.Extendee, err = r.findMessageDescriptor(x.Parent().FullName(), partialName(xd.GetExtendee()), false); err != nil { - return errors.New("extension field %q cannot resolve extendee: %v", x.FullName(), err) - } - if x.L1.Kind, x.L2.Enum, x.L2.Message, err = r.findTarget(x.Kind(), x.Parent().FullName(), partialName(xd.GetTypeName()), false); err != nil { - return errors.New("extension field %q cannot resolve type: %v", x.FullName(), err) - } - if xd.DefaultValue != nil { - v, ev, err := unmarshalDefault(xd.GetDefaultValue(), x, r.allowUnresolvable) - if err != nil { - return errors.New("extension field %q has invalid default: %v", x.FullName(), err) - } - x.L2.Default = filedesc.DefaultValue(v, ev) - } - } - return nil -} - -func (r *resolver) resolveServiceDependencies(ss []filedesc.Service, sds []*descriptorpb.ServiceDescriptorProto) (err error) { - for i, sd := range sds { - s := &ss[i] - for j, md := range sd.GetMethod() { - m := &s.L2.Methods.List[j] - m.L1.Input, err = r.findMessageDescriptor(m.Parent().FullName(), partialName(md.GetInputType()), false) - if err != nil { - return errors.New("service method %q cannot resolve input: %v", m.FullName(), err) - } - m.L1.Output, err = r.findMessageDescriptor(s.FullName(), partialName(md.GetOutputType()), false) - if err != nil { - return errors.New("service method %q cannot resolve output: %v", m.FullName(), err) - } - } - } - return nil -} - -// findTarget finds an enum or message descriptor if k is an enum, message, -// group, or unknown. If unknown, and the name could be resolved, the kind -// returned kind is set based on the type of the resolved descriptor. -func (r *resolver) findTarget(k protoreflect.Kind, scope protoreflect.FullName, ref partialName, isWeak bool) (protoreflect.Kind, protoreflect.EnumDescriptor, protoreflect.MessageDescriptor, error) { - switch k { - case protoreflect.EnumKind: - ed, err := r.findEnumDescriptor(scope, ref, isWeak) - if err != nil { - return 0, nil, nil, err - } - return k, ed, nil, nil - case protoreflect.MessageKind, protoreflect.GroupKind: - md, err := r.findMessageDescriptor(scope, ref, isWeak) - if err != nil { - return 0, nil, nil, err - } - return k, nil, md, nil - case 0: - // Handle unspecified kinds (possible with parsers that operate - // on a per-file basis without knowledge of dependencies). - d, err := r.findDescriptor(scope, ref) - if err == protoregistry.NotFound && (r.allowUnresolvable || isWeak) { - return k, filedesc.PlaceholderEnum(ref.FullName()), filedesc.PlaceholderMessage(ref.FullName()), nil - } else if err == protoregistry.NotFound { - return 0, nil, nil, errors.New("%q not found", ref.FullName()) - } else if err != nil { - return 0, nil, nil, err - } - switch d := d.(type) { - case protoreflect.EnumDescriptor: - return protoreflect.EnumKind, d, nil, nil - case protoreflect.MessageDescriptor: - return protoreflect.MessageKind, nil, d, nil - default: - return 0, nil, nil, errors.New("unknown kind") - } - default: - if ref != "" { - return 0, nil, nil, errors.New("target name cannot be specified for %v", k) - } - if !k.IsValid() { - return 0, nil, nil, errors.New("invalid kind: %d", k) - } - return k, nil, nil, nil - } -} - -// findDescriptor finds the descriptor by name, -// which may be a relative name within some scope. -// -// Suppose the scope was "fizz.buzz" and the reference was "Foo.Bar", -// then the following full names are searched: -// - fizz.buzz.Foo.Bar -// - fizz.Foo.Bar -// - Foo.Bar -func (r *resolver) findDescriptor(scope protoreflect.FullName, ref partialName) (protoreflect.Descriptor, error) { - if !ref.IsValid() { - return nil, errors.New("invalid name reference: %q", ref) - } - if ref.IsFull() { - scope, ref = "", ref[1:] - } - var foundButNotImported protoreflect.Descriptor - for { - // Derive the full name to search. - s := protoreflect.FullName(ref) - if scope != "" { - s = scope + "." + s - } - - // Check the current file for the descriptor. - if d, ok := r.local[s]; ok { - return d, nil - } - - // Check the remote registry for the descriptor. - d, err := r.remote.FindDescriptorByName(s) - if err == nil { - // Only allow descriptors covered by one of the imports. - if r.imports[d.ParentFile().Path()] { - return d, nil - } - foundButNotImported = d - } else if err != protoregistry.NotFound { - return nil, errors.Wrap(err, "%q", s) - } - - // Continue on at a higher level of scoping. - if scope == "" { - if d := foundButNotImported; d != nil { - return nil, errors.New("resolved %q, but %q is not imported", d.FullName(), d.ParentFile().Path()) - } - return nil, protoregistry.NotFound - } - scope = scope.Parent() - } -} - -func (r *resolver) findEnumDescriptor(scope protoreflect.FullName, ref partialName, isWeak bool) (protoreflect.EnumDescriptor, error) { - d, err := r.findDescriptor(scope, ref) - if err == protoregistry.NotFound && (r.allowUnresolvable || isWeak) { - return filedesc.PlaceholderEnum(ref.FullName()), nil - } else if err == protoregistry.NotFound { - return nil, errors.New("%q not found", ref.FullName()) - } else if err != nil { - return nil, err - } - ed, ok := d.(protoreflect.EnumDescriptor) - if !ok { - return nil, errors.New("resolved %q, but it is not an enum", d.FullName()) - } - return ed, nil -} - -func (r *resolver) findMessageDescriptor(scope protoreflect.FullName, ref partialName, isWeak bool) (protoreflect.MessageDescriptor, error) { - d, err := r.findDescriptor(scope, ref) - if err == protoregistry.NotFound && (r.allowUnresolvable || isWeak) { - return filedesc.PlaceholderMessage(ref.FullName()), nil - } else if err == protoregistry.NotFound { - return nil, errors.New("%q not found", ref.FullName()) - } else if err != nil { - return nil, err - } - md, ok := d.(protoreflect.MessageDescriptor) - if !ok { - return nil, errors.New("resolved %q, but it is not an message", d.FullName()) - } - return md, nil -} - -// partialName is the partial name. A leading dot means that the name is full, -// otherwise the name is relative to some current scope. -// See google.protobuf.FieldDescriptorProto.type_name. -type partialName string - -func (s partialName) IsFull() bool { - return len(s) > 0 && s[0] == '.' -} - -func (s partialName) IsValid() bool { - if s.IsFull() { - return protoreflect.FullName(s[1:]).IsValid() - } - return protoreflect.FullName(s).IsValid() -} - -const unknownPrefix = "*." - -// FullName converts the partial name to a full name on a best-effort basis. -// If relative, it creates an invalid full name, using a "*." prefix -// to indicate that the start of the full name is unknown. -func (s partialName) FullName() protoreflect.FullName { - if s.IsFull() { - return protoreflect.FullName(s[1:]) - } - return protoreflect.FullName(unknownPrefix + s) -} - -func unmarshalDefault(s string, fd protoreflect.FieldDescriptor, allowUnresolvable bool) (protoreflect.Value, protoreflect.EnumValueDescriptor, error) { - var evs protoreflect.EnumValueDescriptors - if fd.Enum() != nil { - evs = fd.Enum().Values() - } - v, ev, err := defval.Unmarshal(s, fd.Kind(), evs, defval.Descriptor) - if err != nil && allowUnresolvable && evs != nil && protoreflect.Name(s).IsValid() { - v = protoreflect.ValueOfEnum(0) - if evs.Len() > 0 { - v = protoreflect.ValueOfEnum(evs.Get(0).Number()) - } - ev = filedesc.PlaceholderEnumValue(fd.Enum().FullName().Parent().Append(protoreflect.Name(s))) - } else if err != nil { - return v, ev, err - } - if !fd.HasPresence() { - return v, ev, errors.New("cannot be specified with implicit field presence") - } - if fd.Kind() == protoreflect.MessageKind || fd.Kind() == protoreflect.GroupKind || fd.Cardinality() == protoreflect.Repeated { - return v, ev, errors.New("cannot be specified on composite types") - } - return v, ev, nil -} diff --git a/go-controller/vendor/google.golang.org/protobuf/reflect/protodesc/desc_validate.go b/go-controller/vendor/google.golang.org/protobuf/reflect/protodesc/desc_validate.go deleted file mode 100644 index 6de31c2ebd..0000000000 --- a/go-controller/vendor/google.golang.org/protobuf/reflect/protodesc/desc_validate.go +++ /dev/null @@ -1,371 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package protodesc - -import ( - "strings" - "unicode" - - "google.golang.org/protobuf/encoding/protowire" - "google.golang.org/protobuf/internal/errors" - "google.golang.org/protobuf/internal/filedesc" - "google.golang.org/protobuf/internal/flags" - "google.golang.org/protobuf/internal/genid" - "google.golang.org/protobuf/internal/strs" - "google.golang.org/protobuf/reflect/protoreflect" - - "google.golang.org/protobuf/types/descriptorpb" -) - -func validateEnumDeclarations(es []filedesc.Enum, eds []*descriptorpb.EnumDescriptorProto) error { - for i, ed := range eds { - e := &es[i] - if err := e.L2.ReservedNames.CheckValid(); err != nil { - return errors.New("enum %q reserved names has %v", e.FullName(), err) - } - if err := e.L2.ReservedRanges.CheckValid(); err != nil { - return errors.New("enum %q reserved ranges has %v", e.FullName(), err) - } - if len(ed.GetValue()) == 0 { - return errors.New("enum %q must contain at least one value declaration", e.FullName()) - } - allowAlias := ed.GetOptions().GetAllowAlias() - foundAlias := false - for i := 0; i < e.Values().Len(); i++ { - v1 := e.Values().Get(i) - if v2 := e.Values().ByNumber(v1.Number()); v1 != v2 { - foundAlias = true - if !allowAlias { - return errors.New("enum %q has conflicting non-aliased values on number %d: %q with %q", e.FullName(), v1.Number(), v1.Name(), v2.Name()) - } - } - } - if allowAlias && !foundAlias { - return errors.New("enum %q allows aliases, but none were found", e.FullName()) - } - if !e.IsClosed() { - if v := e.Values().Get(0); v.Number() != 0 { - return errors.New("enum %q using open semantics must have zero number for the first value", v.FullName()) - } - // Verify that value names in open enums do not conflict if the - // case-insensitive prefix is removed. - // See protoc v3.8.0: src/google/protobuf/descriptor.cc:4991-5055 - names := map[string]protoreflect.EnumValueDescriptor{} - prefix := strings.Replace(strings.ToLower(string(e.Name())), "_", "", -1) - for i := 0; i < e.Values().Len(); i++ { - v1 := e.Values().Get(i) - s := strs.EnumValueName(strs.TrimEnumPrefix(string(v1.Name()), prefix)) - if v2, ok := names[s]; ok && v1.Number() != v2.Number() { - return errors.New("enum %q using open semantics has conflict: %q with %q", e.FullName(), v1.Name(), v2.Name()) - } - names[s] = v1 - } - } - - for j, vd := range ed.GetValue() { - v := &e.L2.Values.List[j] - if vd.Number == nil { - return errors.New("enum value %q must have a specified number", v.FullName()) - } - if e.L2.ReservedNames.Has(v.Name()) { - return errors.New("enum value %q must not use reserved name", v.FullName()) - } - if e.L2.ReservedRanges.Has(v.Number()) { - return errors.New("enum value %q must not use reserved number %d", v.FullName(), v.Number()) - } - } - } - return nil -} - -func validateMessageDeclarations(file *filedesc.File, ms []filedesc.Message, mds []*descriptorpb.DescriptorProto) error { - // There are a few limited exceptions only for proto3 - isProto3 := file.L1.Edition == fromEditionProto(descriptorpb.Edition_EDITION_PROTO3) - for i, md := range mds { - m := &ms[i] - - // Handle the message descriptor itself. - isMessageSet := md.GetOptions().GetMessageSetWireFormat() - if err := m.L2.ReservedNames.CheckValid(); err != nil { - return errors.New("message %q reserved names has %v", m.FullName(), err) - } - if err := m.L2.ReservedRanges.CheckValid(isMessageSet); err != nil { - return errors.New("message %q reserved ranges has %v", m.FullName(), err) - } - if err := m.L2.ExtensionRanges.CheckValid(isMessageSet); err != nil { - return errors.New("message %q extension ranges has %v", m.FullName(), err) - } - if err := (*filedesc.FieldRanges).CheckOverlap(&m.L2.ReservedRanges, &m.L2.ExtensionRanges); err != nil { - return errors.New("message %q reserved and extension ranges has %v", m.FullName(), err) - } - for i := 0; i < m.Fields().Len(); i++ { - f1 := m.Fields().Get(i) - if f2 := m.Fields().ByNumber(f1.Number()); f1 != f2 { - return errors.New("message %q has conflicting fields: %q with %q", m.FullName(), f1.Name(), f2.Name()) - } - } - if isMessageSet && !flags.ProtoLegacy { - return errors.New("message %q is a MessageSet, which is a legacy proto1 feature that is no longer supported", m.FullName()) - } - if isMessageSet && (isProto3 || m.Fields().Len() > 0 || m.ExtensionRanges().Len() == 0) { - return errors.New("message %q is an invalid proto1 MessageSet", m.FullName()) - } - if isProto3 { - if m.ExtensionRanges().Len() > 0 { - return errors.New("message %q using proto3 semantics cannot have extension ranges", m.FullName()) - } - } - - for j, fd := range md.GetField() { - f := &m.L2.Fields.List[j] - if m.L2.ReservedNames.Has(f.Name()) { - return errors.New("message field %q must not use reserved name", f.FullName()) - } - if !f.Number().IsValid() { - return errors.New("message field %q has an invalid number: %d", f.FullName(), f.Number()) - } - if !f.Cardinality().IsValid() { - return errors.New("message field %q has an invalid cardinality: %d", f.FullName(), f.Cardinality()) - } - if m.L2.ReservedRanges.Has(f.Number()) { - return errors.New("message field %q must not use reserved number %d", f.FullName(), f.Number()) - } - if m.L2.ExtensionRanges.Has(f.Number()) { - return errors.New("message field %q with number %d in extension range", f.FullName(), f.Number()) - } - if fd.Extendee != nil { - return errors.New("message field %q may not have extendee: %q", f.FullName(), fd.GetExtendee()) - } - if f.L1.IsProto3Optional { - if !isProto3 { - return errors.New("message field %q under proto3 optional semantics must be specified in the proto3 syntax", f.FullName()) - } - if f.Cardinality() != protoreflect.Optional { - return errors.New("message field %q under proto3 optional semantics must have optional cardinality", f.FullName()) - } - if f.ContainingOneof() != nil && f.ContainingOneof().Fields().Len() != 1 { - return errors.New("message field %q under proto3 optional semantics must be within a single element oneof", f.FullName()) - } - } - if f.IsWeak() && !flags.ProtoLegacy { - return errors.New("message field %q is a weak field, which is a legacy proto1 feature that is no longer supported", f.FullName()) - } - if f.IsWeak() && (!f.HasPresence() || !isOptionalMessage(f) || f.ContainingOneof() != nil) { - return errors.New("message field %q may only be weak for an optional message", f.FullName()) - } - if f.IsPacked() && !isPackable(f) { - return errors.New("message field %q is not packable", f.FullName()) - } - if err := checkValidGroup(file, f); err != nil { - return errors.New("message field %q is an invalid group: %v", f.FullName(), err) - } - if err := checkValidMap(f); err != nil { - return errors.New("message field %q is an invalid map: %v", f.FullName(), err) - } - if isProto3 { - if f.Cardinality() == protoreflect.Required { - return errors.New("message field %q using proto3 semantics cannot be required", f.FullName()) - } - if f.Enum() != nil && !f.Enum().IsPlaceholder() && f.Enum().IsClosed() { - return errors.New("message field %q using proto3 semantics may only depend on open enums", f.FullName()) - } - } - if f.Cardinality() == protoreflect.Optional && !f.HasPresence() && f.Enum() != nil && !f.Enum().IsPlaceholder() && f.Enum().IsClosed() { - return errors.New("message field %q with implicit presence may only use open enums", f.FullName()) - } - } - seenSynthetic := false // synthetic oneofs for proto3 optional must come after real oneofs - for j := range md.GetOneofDecl() { - o := &m.L2.Oneofs.List[j] - if o.Fields().Len() == 0 { - return errors.New("message oneof %q must contain at least one field declaration", o.FullName()) - } - if n := o.Fields().Len(); n-1 != (o.Fields().Get(n-1).Index() - o.Fields().Get(0).Index()) { - return errors.New("message oneof %q must have consecutively declared fields", o.FullName()) - } - - if o.IsSynthetic() { - seenSynthetic = true - continue - } - if !o.IsSynthetic() && seenSynthetic { - return errors.New("message oneof %q must be declared before synthetic oneofs", o.FullName()) - } - - for i := 0; i < o.Fields().Len(); i++ { - f := o.Fields().Get(i) - if f.Cardinality() != protoreflect.Optional { - return errors.New("message field %q belongs in a oneof and must be optional", f.FullName()) - } - if f.IsWeak() { - return errors.New("message field %q belongs in a oneof and must not be a weak reference", f.FullName()) - } - } - } - - if err := validateEnumDeclarations(m.L1.Enums.List, md.GetEnumType()); err != nil { - return err - } - if err := validateMessageDeclarations(file, m.L1.Messages.List, md.GetNestedType()); err != nil { - return err - } - if err := validateExtensionDeclarations(file, m.L1.Extensions.List, md.GetExtension()); err != nil { - return err - } - } - return nil -} - -func validateExtensionDeclarations(f *filedesc.File, xs []filedesc.Extension, xds []*descriptorpb.FieldDescriptorProto) error { - for i, xd := range xds { - x := &xs[i] - // NOTE: Avoid using the IsValid method since extensions to MessageSet - // may have a field number higher than normal. This check only verifies - // that the number is not negative or reserved. We check again later - // if we know that the extendee is definitely not a MessageSet. - if n := x.Number(); n < 0 || (protowire.FirstReservedNumber <= n && n <= protowire.LastReservedNumber) { - return errors.New("extension field %q has an invalid number: %d", x.FullName(), x.Number()) - } - if !x.Cardinality().IsValid() || x.Cardinality() == protoreflect.Required { - return errors.New("extension field %q has an invalid cardinality: %d", x.FullName(), x.Cardinality()) - } - if xd.JsonName != nil { - // A bug in older versions of protoc would always populate the - // "json_name" option for extensions when it is meaningless. - // When it did so, it would always use the camel-cased field name. - if xd.GetJsonName() != strs.JSONCamelCase(string(x.Name())) { - return errors.New("extension field %q may not have an explicitly set JSON name: %q", x.FullName(), xd.GetJsonName()) - } - } - if xd.OneofIndex != nil { - return errors.New("extension field %q may not be part of a oneof", x.FullName()) - } - if md := x.ContainingMessage(); !md.IsPlaceholder() { - if !md.ExtensionRanges().Has(x.Number()) { - return errors.New("extension field %q extends %q with non-extension field number: %d", x.FullName(), md.FullName(), x.Number()) - } - isMessageSet := md.Options().(*descriptorpb.MessageOptions).GetMessageSetWireFormat() - if isMessageSet && !isOptionalMessage(x) { - return errors.New("extension field %q extends MessageSet and must be an optional message", x.FullName()) - } - if !isMessageSet && !x.Number().IsValid() { - return errors.New("extension field %q has an invalid number: %d", x.FullName(), x.Number()) - } - } - if xd.GetOptions().GetWeak() { - return errors.New("extension field %q cannot be a weak reference", x.FullName()) - } - if x.IsPacked() && !isPackable(x) { - return errors.New("extension field %q is not packable", x.FullName()) - } - if err := checkValidGroup(f, x); err != nil { - return errors.New("extension field %q is an invalid group: %v", x.FullName(), err) - } - if md := x.Message(); md != nil && md.IsMapEntry() { - return errors.New("extension field %q cannot be a map entry", x.FullName()) - } - if f.L1.Edition == fromEditionProto(descriptorpb.Edition_EDITION_PROTO3) { - switch x.ContainingMessage().FullName() { - case (*descriptorpb.FileOptions)(nil).ProtoReflect().Descriptor().FullName(): - case (*descriptorpb.EnumOptions)(nil).ProtoReflect().Descriptor().FullName(): - case (*descriptorpb.EnumValueOptions)(nil).ProtoReflect().Descriptor().FullName(): - case (*descriptorpb.MessageOptions)(nil).ProtoReflect().Descriptor().FullName(): - case (*descriptorpb.FieldOptions)(nil).ProtoReflect().Descriptor().FullName(): - case (*descriptorpb.OneofOptions)(nil).ProtoReflect().Descriptor().FullName(): - case (*descriptorpb.ExtensionRangeOptions)(nil).ProtoReflect().Descriptor().FullName(): - case (*descriptorpb.ServiceOptions)(nil).ProtoReflect().Descriptor().FullName(): - case (*descriptorpb.MethodOptions)(nil).ProtoReflect().Descriptor().FullName(): - default: - return errors.New("extension field %q cannot be declared in proto3 unless extended descriptor options", x.FullName()) - } - } - } - return nil -} - -// isOptionalMessage reports whether this is an optional message. -// If the kind is unknown, it is assumed to be a message. -func isOptionalMessage(fd protoreflect.FieldDescriptor) bool { - return (fd.Kind() == 0 || fd.Kind() == protoreflect.MessageKind) && fd.Cardinality() == protoreflect.Optional -} - -// isPackable checks whether the pack option can be specified. -func isPackable(fd protoreflect.FieldDescriptor) bool { - switch fd.Kind() { - case protoreflect.StringKind, protoreflect.BytesKind, protoreflect.MessageKind, protoreflect.GroupKind: - return false - } - return fd.IsList() -} - -// checkValidGroup reports whether fd is a valid group according to the same -// rules that protoc imposes. -func checkValidGroup(f *filedesc.File, fd protoreflect.FieldDescriptor) error { - md := fd.Message() - switch { - case fd.Kind() != protoreflect.GroupKind: - return nil - case f.L1.Edition == fromEditionProto(descriptorpb.Edition_EDITION_PROTO3): - return errors.New("invalid under proto3 semantics") - case md == nil || md.IsPlaceholder(): - return errors.New("message must be resolvable") - } - if f.L1.Edition < fromEditionProto(descriptorpb.Edition_EDITION_2023) { - switch { - case fd.FullName().Parent() != md.FullName().Parent(): - return errors.New("message and field must be declared in the same scope") - case !unicode.IsUpper(rune(md.Name()[0])): - return errors.New("message name must start with an uppercase") - case fd.Name() != protoreflect.Name(strings.ToLower(string(md.Name()))): - return errors.New("field name must be lowercased form of the message name") - } - } - return nil -} - -// checkValidMap checks whether the field is a valid map according to the same -// rules that protoc imposes. -// See protoc v3.8.0: src/google/protobuf/descriptor.cc:6045-6115 -func checkValidMap(fd protoreflect.FieldDescriptor) error { - md := fd.Message() - switch { - case md == nil || !md.IsMapEntry(): - return nil - case fd.FullName().Parent() != md.FullName().Parent(): - return errors.New("message and field must be declared in the same scope") - case md.Name() != protoreflect.Name(strs.MapEntryName(string(fd.Name()))): - return errors.New("incorrect implicit map entry name") - case fd.Cardinality() != protoreflect.Repeated: - return errors.New("field must be repeated") - case md.Fields().Len() != 2: - return errors.New("message must have exactly two fields") - case md.ExtensionRanges().Len() > 0: - return errors.New("message must not have any extension ranges") - case md.Enums().Len()+md.Messages().Len()+md.Extensions().Len() > 0: - return errors.New("message must not have any nested declarations") - } - kf := md.Fields().Get(0) - vf := md.Fields().Get(1) - switch { - case kf.Name() != genid.MapEntry_Key_field_name || kf.Number() != genid.MapEntry_Key_field_number || kf.Cardinality() != protoreflect.Optional || kf.ContainingOneof() != nil || kf.HasDefault(): - return errors.New("invalid key field") - case vf.Name() != genid.MapEntry_Value_field_name || vf.Number() != genid.MapEntry_Value_field_number || vf.Cardinality() != protoreflect.Optional || vf.ContainingOneof() != nil || vf.HasDefault(): - return errors.New("invalid value field") - } - switch kf.Kind() { - case protoreflect.BoolKind: // bool - case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind: // int32 - case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind: // int64 - case protoreflect.Uint32Kind, protoreflect.Fixed32Kind: // uint32 - case protoreflect.Uint64Kind, protoreflect.Fixed64Kind: // uint64 - case protoreflect.StringKind: // string - default: - return errors.New("invalid key kind: %v", kf.Kind()) - } - if e := vf.Enum(); e != nil && e.Values().Len() > 0 && e.Values().Get(0).Number() != 0 { - return errors.New("map enum value must have zero number for the first value") - } - return nil -} diff --git a/go-controller/vendor/google.golang.org/protobuf/reflect/protodesc/editions.go b/go-controller/vendor/google.golang.org/protobuf/reflect/protodesc/editions.go deleted file mode 100644 index 002e0047ae..0000000000 --- a/go-controller/vendor/google.golang.org/protobuf/reflect/protodesc/editions.go +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package protodesc - -import ( - "fmt" - "os" - "sync" - - "google.golang.org/protobuf/internal/editiondefaults" - "google.golang.org/protobuf/internal/filedesc" - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/types/descriptorpb" - "google.golang.org/protobuf/types/gofeaturespb" -) - -var defaults = &descriptorpb.FeatureSetDefaults{} -var defaultsCacheMu sync.Mutex -var defaultsCache = make(map[filedesc.Edition]*descriptorpb.FeatureSet) - -func init() { - err := proto.Unmarshal(editiondefaults.Defaults, defaults) - if err != nil { - fmt.Fprintf(os.Stderr, "unmarshal editions defaults: %v\n", err) - os.Exit(1) - } -} - -func fromEditionProto(epb descriptorpb.Edition) filedesc.Edition { - return filedesc.Edition(epb) -} - -func toEditionProto(ed filedesc.Edition) descriptorpb.Edition { - switch ed { - case filedesc.EditionUnknown: - return descriptorpb.Edition_EDITION_UNKNOWN - case filedesc.EditionProto2: - return descriptorpb.Edition_EDITION_PROTO2 - case filedesc.EditionProto3: - return descriptorpb.Edition_EDITION_PROTO3 - case filedesc.Edition2023: - return descriptorpb.Edition_EDITION_2023 - default: - panic(fmt.Sprintf("unknown value for edition: %v", ed)) - } -} - -func getFeatureSetFor(ed filedesc.Edition) *descriptorpb.FeatureSet { - defaultsCacheMu.Lock() - defer defaultsCacheMu.Unlock() - if def, ok := defaultsCache[ed]; ok { - return def - } - edpb := toEditionProto(ed) - if defaults.GetMinimumEdition() > edpb || defaults.GetMaximumEdition() < edpb { - // This should never happen protodesc.(FileOptions).New would fail when - // initializing the file descriptor. - // This most likely means the embedded defaults were not updated. - fmt.Fprintf(os.Stderr, "internal error: unsupported edition %v (did you forget to update the embedded defaults (i.e. the bootstrap descriptor proto)?)\n", edpb) - os.Exit(1) - } - fsed := defaults.GetDefaults()[0] - // Using a linear search for now. - // Editions are guaranteed to be sorted and thus we could use a binary search. - // Given that there are only a handful of editions (with one more per year) - // there is not much reason to use a binary search. - for _, def := range defaults.GetDefaults() { - if def.GetEdition() <= edpb { - fsed = def - } else { - break - } - } - fs := proto.Clone(fsed.GetFixedFeatures()).(*descriptorpb.FeatureSet) - proto.Merge(fs, fsed.GetOverridableFeatures()) - defaultsCache[ed] = fs - return fs -} - -// mergeEditionFeatures merges the parent and child feature sets. This function -// should be used when initializing Go descriptors from descriptor protos which -// is why the parent is a filedesc.EditionsFeatures (Go representation) while -// the child is a descriptorproto.FeatureSet (protoc representation). -// Any feature set by the child overwrites what is set by the parent. -func mergeEditionFeatures(parentDesc protoreflect.Descriptor, child *descriptorpb.FeatureSet) filedesc.EditionFeatures { - var parentFS filedesc.EditionFeatures - switch p := parentDesc.(type) { - case *filedesc.File: - parentFS = p.L1.EditionFeatures - case *filedesc.Message: - parentFS = p.L1.EditionFeatures - default: - panic(fmt.Sprintf("unknown parent type %T", parentDesc)) - } - if child == nil { - return parentFS - } - if fp := child.FieldPresence; fp != nil { - parentFS.IsFieldPresence = *fp == descriptorpb.FeatureSet_LEGACY_REQUIRED || - *fp == descriptorpb.FeatureSet_EXPLICIT - parentFS.IsLegacyRequired = *fp == descriptorpb.FeatureSet_LEGACY_REQUIRED - } - if et := child.EnumType; et != nil { - parentFS.IsOpenEnum = *et == descriptorpb.FeatureSet_OPEN - } - - if rfe := child.RepeatedFieldEncoding; rfe != nil { - parentFS.IsPacked = *rfe == descriptorpb.FeatureSet_PACKED - } - - if utf8val := child.Utf8Validation; utf8val != nil { - parentFS.IsUTF8Validated = *utf8val == descriptorpb.FeatureSet_VERIFY - } - - if me := child.MessageEncoding; me != nil { - parentFS.IsDelimitedEncoded = *me == descriptorpb.FeatureSet_DELIMITED - } - - if jf := child.JsonFormat; jf != nil { - parentFS.IsJSONCompliant = *jf == descriptorpb.FeatureSet_ALLOW - } - - if goFeatures, ok := proto.GetExtension(child, gofeaturespb.E_Go).(*gofeaturespb.GoFeatures); ok && goFeatures != nil { - if luje := goFeatures.LegacyUnmarshalJsonEnum; luje != nil { - parentFS.GenerateLegacyUnmarshalJSON = *luje - } - } - - return parentFS -} - -// initFileDescFromFeatureSet initializes editions related fields in fd based -// on fs. If fs is nil it is assumed to be an empty featureset and all fields -// will be initialized with the appropriate default. fd.L1.Edition must be set -// before calling this function. -func initFileDescFromFeatureSet(fd *filedesc.File, fs *descriptorpb.FeatureSet) { - dfs := getFeatureSetFor(fd.L1.Edition) - // initialize the featureset with the defaults - fd.L1.EditionFeatures = mergeEditionFeatures(fd, dfs) - // overwrite any options explicitly specified - fd.L1.EditionFeatures = mergeEditionFeatures(fd, fs) -} diff --git a/go-controller/vendor/google.golang.org/protobuf/reflect/protodesc/proto.go b/go-controller/vendor/google.golang.org/protobuf/reflect/protodesc/proto.go deleted file mode 100644 index a5de8d4001..0000000000 --- a/go-controller/vendor/google.golang.org/protobuf/reflect/protodesc/proto.go +++ /dev/null @@ -1,274 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package protodesc - -import ( - "fmt" - "strings" - - "google.golang.org/protobuf/internal/encoding/defval" - "google.golang.org/protobuf/internal/strs" - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/reflect/protoreflect" - - "google.golang.org/protobuf/types/descriptorpb" -) - -// ToFileDescriptorProto copies a [protoreflect.FileDescriptor] into a -// google.protobuf.FileDescriptorProto message. -func ToFileDescriptorProto(file protoreflect.FileDescriptor) *descriptorpb.FileDescriptorProto { - p := &descriptorpb.FileDescriptorProto{ - Name: proto.String(file.Path()), - Options: proto.Clone(file.Options()).(*descriptorpb.FileOptions), - } - if file.Package() != "" { - p.Package = proto.String(string(file.Package())) - } - for i, imports := 0, file.Imports(); i < imports.Len(); i++ { - imp := imports.Get(i) - p.Dependency = append(p.Dependency, imp.Path()) - if imp.IsPublic { - p.PublicDependency = append(p.PublicDependency, int32(i)) - } - if imp.IsWeak { - p.WeakDependency = append(p.WeakDependency, int32(i)) - } - } - for i, locs := 0, file.SourceLocations(); i < locs.Len(); i++ { - loc := locs.Get(i) - l := &descriptorpb.SourceCodeInfo_Location{} - l.Path = append(l.Path, loc.Path...) - if loc.StartLine == loc.EndLine { - l.Span = []int32{int32(loc.StartLine), int32(loc.StartColumn), int32(loc.EndColumn)} - } else { - l.Span = []int32{int32(loc.StartLine), int32(loc.StartColumn), int32(loc.EndLine), int32(loc.EndColumn)} - } - l.LeadingDetachedComments = append([]string(nil), loc.LeadingDetachedComments...) - if loc.LeadingComments != "" { - l.LeadingComments = proto.String(loc.LeadingComments) - } - if loc.TrailingComments != "" { - l.TrailingComments = proto.String(loc.TrailingComments) - } - if p.SourceCodeInfo == nil { - p.SourceCodeInfo = &descriptorpb.SourceCodeInfo{} - } - p.SourceCodeInfo.Location = append(p.SourceCodeInfo.Location, l) - - } - for i, messages := 0, file.Messages(); i < messages.Len(); i++ { - p.MessageType = append(p.MessageType, ToDescriptorProto(messages.Get(i))) - } - for i, enums := 0, file.Enums(); i < enums.Len(); i++ { - p.EnumType = append(p.EnumType, ToEnumDescriptorProto(enums.Get(i))) - } - for i, services := 0, file.Services(); i < services.Len(); i++ { - p.Service = append(p.Service, ToServiceDescriptorProto(services.Get(i))) - } - for i, exts := 0, file.Extensions(); i < exts.Len(); i++ { - p.Extension = append(p.Extension, ToFieldDescriptorProto(exts.Get(i))) - } - if syntax := file.Syntax(); syntax != protoreflect.Proto2 && syntax.IsValid() { - p.Syntax = proto.String(file.Syntax().String()) - } - if file.Syntax() == protoreflect.Editions { - desc := file - if fileImportDesc, ok := file.(protoreflect.FileImport); ok { - desc = fileImportDesc.FileDescriptor - } - - if editionsInterface, ok := desc.(interface{ Edition() int32 }); ok { - p.Edition = descriptorpb.Edition(editionsInterface.Edition()).Enum() - } - } - return p -} - -// ToDescriptorProto copies a [protoreflect.MessageDescriptor] into a -// google.protobuf.DescriptorProto message. -func ToDescriptorProto(message protoreflect.MessageDescriptor) *descriptorpb.DescriptorProto { - p := &descriptorpb.DescriptorProto{ - Name: proto.String(string(message.Name())), - Options: proto.Clone(message.Options()).(*descriptorpb.MessageOptions), - } - for i, fields := 0, message.Fields(); i < fields.Len(); i++ { - p.Field = append(p.Field, ToFieldDescriptorProto(fields.Get(i))) - } - for i, exts := 0, message.Extensions(); i < exts.Len(); i++ { - p.Extension = append(p.Extension, ToFieldDescriptorProto(exts.Get(i))) - } - for i, messages := 0, message.Messages(); i < messages.Len(); i++ { - p.NestedType = append(p.NestedType, ToDescriptorProto(messages.Get(i))) - } - for i, enums := 0, message.Enums(); i < enums.Len(); i++ { - p.EnumType = append(p.EnumType, ToEnumDescriptorProto(enums.Get(i))) - } - for i, xranges := 0, message.ExtensionRanges(); i < xranges.Len(); i++ { - xrange := xranges.Get(i) - p.ExtensionRange = append(p.ExtensionRange, &descriptorpb.DescriptorProto_ExtensionRange{ - Start: proto.Int32(int32(xrange[0])), - End: proto.Int32(int32(xrange[1])), - Options: proto.Clone(message.ExtensionRangeOptions(i)).(*descriptorpb.ExtensionRangeOptions), - }) - } - for i, oneofs := 0, message.Oneofs(); i < oneofs.Len(); i++ { - p.OneofDecl = append(p.OneofDecl, ToOneofDescriptorProto(oneofs.Get(i))) - } - for i, ranges := 0, message.ReservedRanges(); i < ranges.Len(); i++ { - rrange := ranges.Get(i) - p.ReservedRange = append(p.ReservedRange, &descriptorpb.DescriptorProto_ReservedRange{ - Start: proto.Int32(int32(rrange[0])), - End: proto.Int32(int32(rrange[1])), - }) - } - for i, names := 0, message.ReservedNames(); i < names.Len(); i++ { - p.ReservedName = append(p.ReservedName, string(names.Get(i))) - } - return p -} - -// ToFieldDescriptorProto copies a [protoreflect.FieldDescriptor] into a -// google.protobuf.FieldDescriptorProto message. -func ToFieldDescriptorProto(field protoreflect.FieldDescriptor) *descriptorpb.FieldDescriptorProto { - p := &descriptorpb.FieldDescriptorProto{ - Name: proto.String(string(field.Name())), - Number: proto.Int32(int32(field.Number())), - Label: descriptorpb.FieldDescriptorProto_Label(field.Cardinality()).Enum(), - Options: proto.Clone(field.Options()).(*descriptorpb.FieldOptions), - } - if field.IsExtension() { - p.Extendee = fullNameOf(field.ContainingMessage()) - } - if field.Kind().IsValid() { - p.Type = descriptorpb.FieldDescriptorProto_Type(field.Kind()).Enum() - } - if field.Enum() != nil { - p.TypeName = fullNameOf(field.Enum()) - } - if field.Message() != nil { - p.TypeName = fullNameOf(field.Message()) - } - if field.HasJSONName() { - // A bug in older versions of protoc would always populate the - // "json_name" option for extensions when it is meaningless. - // When it did so, it would always use the camel-cased field name. - if field.IsExtension() { - p.JsonName = proto.String(strs.JSONCamelCase(string(field.Name()))) - } else { - p.JsonName = proto.String(field.JSONName()) - } - } - if field.Syntax() == protoreflect.Proto3 && field.HasOptionalKeyword() { - p.Proto3Optional = proto.Bool(true) - } - if field.Syntax() == protoreflect.Editions { - // Editions have no group keyword, this type is only set so that downstream users continue - // treating this as delimited encoding. - if p.GetType() == descriptorpb.FieldDescriptorProto_TYPE_GROUP { - p.Type = descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum() - } - // Editions have no required keyword, this label is only set so that downstream users continue - // treating it as required. - if p.GetLabel() == descriptorpb.FieldDescriptorProto_LABEL_REQUIRED { - p.Label = descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum() - } - } - if field.HasDefault() { - def, err := defval.Marshal(field.Default(), field.DefaultEnumValue(), field.Kind(), defval.Descriptor) - if err != nil && field.DefaultEnumValue() != nil { - def = string(field.DefaultEnumValue().Name()) // occurs for unresolved enum values - } else if err != nil { - panic(fmt.Sprintf("%v: %v", field.FullName(), err)) - } - p.DefaultValue = proto.String(def) - } - if oneof := field.ContainingOneof(); oneof != nil { - p.OneofIndex = proto.Int32(int32(oneof.Index())) - } - return p -} - -// ToOneofDescriptorProto copies a [protoreflect.OneofDescriptor] into a -// google.protobuf.OneofDescriptorProto message. -func ToOneofDescriptorProto(oneof protoreflect.OneofDescriptor) *descriptorpb.OneofDescriptorProto { - return &descriptorpb.OneofDescriptorProto{ - Name: proto.String(string(oneof.Name())), - Options: proto.Clone(oneof.Options()).(*descriptorpb.OneofOptions), - } -} - -// ToEnumDescriptorProto copies a [protoreflect.EnumDescriptor] into a -// google.protobuf.EnumDescriptorProto message. -func ToEnumDescriptorProto(enum protoreflect.EnumDescriptor) *descriptorpb.EnumDescriptorProto { - p := &descriptorpb.EnumDescriptorProto{ - Name: proto.String(string(enum.Name())), - Options: proto.Clone(enum.Options()).(*descriptorpb.EnumOptions), - } - for i, values := 0, enum.Values(); i < values.Len(); i++ { - p.Value = append(p.Value, ToEnumValueDescriptorProto(values.Get(i))) - } - for i, ranges := 0, enum.ReservedRanges(); i < ranges.Len(); i++ { - rrange := ranges.Get(i) - p.ReservedRange = append(p.ReservedRange, &descriptorpb.EnumDescriptorProto_EnumReservedRange{ - Start: proto.Int32(int32(rrange[0])), - End: proto.Int32(int32(rrange[1])), - }) - } - for i, names := 0, enum.ReservedNames(); i < names.Len(); i++ { - p.ReservedName = append(p.ReservedName, string(names.Get(i))) - } - return p -} - -// ToEnumValueDescriptorProto copies a [protoreflect.EnumValueDescriptor] into a -// google.protobuf.EnumValueDescriptorProto message. -func ToEnumValueDescriptorProto(value protoreflect.EnumValueDescriptor) *descriptorpb.EnumValueDescriptorProto { - return &descriptorpb.EnumValueDescriptorProto{ - Name: proto.String(string(value.Name())), - Number: proto.Int32(int32(value.Number())), - Options: proto.Clone(value.Options()).(*descriptorpb.EnumValueOptions), - } -} - -// ToServiceDescriptorProto copies a [protoreflect.ServiceDescriptor] into a -// google.protobuf.ServiceDescriptorProto message. -func ToServiceDescriptorProto(service protoreflect.ServiceDescriptor) *descriptorpb.ServiceDescriptorProto { - p := &descriptorpb.ServiceDescriptorProto{ - Name: proto.String(string(service.Name())), - Options: proto.Clone(service.Options()).(*descriptorpb.ServiceOptions), - } - for i, methods := 0, service.Methods(); i < methods.Len(); i++ { - p.Method = append(p.Method, ToMethodDescriptorProto(methods.Get(i))) - } - return p -} - -// ToMethodDescriptorProto copies a [protoreflect.MethodDescriptor] into a -// google.protobuf.MethodDescriptorProto message. -func ToMethodDescriptorProto(method protoreflect.MethodDescriptor) *descriptorpb.MethodDescriptorProto { - p := &descriptorpb.MethodDescriptorProto{ - Name: proto.String(string(method.Name())), - InputType: fullNameOf(method.Input()), - OutputType: fullNameOf(method.Output()), - Options: proto.Clone(method.Options()).(*descriptorpb.MethodOptions), - } - if method.IsStreamingClient() { - p.ClientStreaming = proto.Bool(true) - } - if method.IsStreamingServer() { - p.ServerStreaming = proto.Bool(true) - } - return p -} - -func fullNameOf(d protoreflect.Descriptor) *string { - if d == nil { - return nil - } - if strings.HasPrefix(string(d.FullName()), unknownPrefix) { - return proto.String(string(d.FullName()[len(unknownPrefix):])) - } - return proto.String("." + string(d.FullName())) -} diff --git a/go-controller/vendor/google.golang.org/protobuf/reflect/protoreflect/type.go b/go-controller/vendor/google.golang.org/protobuf/reflect/protoreflect/type.go index cd8fadbaf8..cd7fbc87a4 100644 --- a/go-controller/vendor/google.golang.org/protobuf/reflect/protoreflect/type.go +++ b/go-controller/vendor/google.golang.org/protobuf/reflect/protoreflect/type.go @@ -68,7 +68,7 @@ type Descriptor interface { // dependency is not resolved, in which case only name information is known. // // Placeholder types may only be returned by the following accessors - // as a result of unresolved dependencies or weak imports: + // as a result of unresolved dependencies: // // ╔═══════════════════════════════════╤═════════════════════╗ // ║ Accessor │ Descriptor ║ @@ -168,11 +168,7 @@ type FileImport struct { // The current file and the imported file must be within proto package. IsPublic bool - // IsWeak reports whether this is a weak import, which does not impose - // a direct dependency on the target file. - // - // Weak imports are a legacy proto1 feature. Equivalent behavior is - // achieved using proto2 extension fields or proto3 Any messages. + // Deprecated: support for weak fields has been removed. IsWeak bool } @@ -325,9 +321,7 @@ type FieldDescriptor interface { // specified in the source .proto file. HasOptionalKeyword() bool - // IsWeak reports whether this is a weak field, which does not impose a - // direct dependency on the target type. - // If true, then Message returns a placeholder type. + // Deprecated: support for weak fields has been removed. IsWeak() bool // IsPacked reports whether repeated primitive numeric kinds should be diff --git a/go-controller/vendor/google.golang.org/protobuf/reflect/protoreflect/value.go b/go-controller/vendor/google.golang.org/protobuf/reflect/protoreflect/value.go index a7b0d06ff3..a4b78acef6 100644 --- a/go-controller/vendor/google.golang.org/protobuf/reflect/protoreflect/value.go +++ b/go-controller/vendor/google.golang.org/protobuf/reflect/protoreflect/value.go @@ -152,7 +152,7 @@ type Message interface { // This method may return nil. // // The returned methods type is identical to - // google.golang.org/protobuf/runtime/protoiface.Methods. + // [google.golang.org/protobuf/runtime/protoiface.Methods]. // Consult the protoiface package documentation for details. ProtoMethods() *methods } diff --git a/go-controller/vendor/google.golang.org/protobuf/runtime/protoiface/methods.go b/go-controller/vendor/google.golang.org/protobuf/runtime/protoiface/methods.go index 246156561c..28e9e9f039 100644 --- a/go-controller/vendor/google.golang.org/protobuf/runtime/protoiface/methods.go +++ b/go-controller/vendor/google.golang.org/protobuf/runtime/protoiface/methods.go @@ -122,6 +122,22 @@ type UnmarshalInputFlags = uint8 const ( UnmarshalDiscardUnknown UnmarshalInputFlags = 1 << iota + + // UnmarshalAliasBuffer permits unmarshal operations to alias the input buffer. + // The unmarshaller must not modify the contents of the buffer. + UnmarshalAliasBuffer + + // UnmarshalValidated indicates that validation has already been + // performed on the input buffer. + UnmarshalValidated + + // UnmarshalCheckRequired is set if this unmarshal operation ultimately will care if required fields are + // initialized. + UnmarshalCheckRequired + + // UnmarshalNoLazyDecoding is set if this unmarshal operation should not use + // lazy decoding, even when otherwise available. + UnmarshalNoLazyDecoding ) // UnmarshalOutputFlags are output from the Unmarshal method. diff --git a/go-controller/vendor/google.golang.org/protobuf/runtime/protoimpl/impl.go b/go-controller/vendor/google.golang.org/protobuf/runtime/protoimpl/impl.go index 4a1ab7fb3d..93df1b569b 100644 --- a/go-controller/vendor/google.golang.org/protobuf/runtime/protoimpl/impl.go +++ b/go-controller/vendor/google.golang.org/protobuf/runtime/protoimpl/impl.go @@ -15,6 +15,7 @@ import ( "google.golang.org/protobuf/internal/filedesc" "google.golang.org/protobuf/internal/filetype" "google.golang.org/protobuf/internal/impl" + "google.golang.org/protobuf/internal/protolazy" ) // UnsafeEnabled specifies whether package unsafe can be used. @@ -39,6 +40,9 @@ type ( ExtensionFieldV1 = impl.ExtensionField Pointer = impl.Pointer + + LazyUnmarshalInfo = *protolazy.XXX_lazyUnmarshalInfo + RaceDetectHookData = impl.RaceDetectHookData ) var X impl.Export diff --git a/go-controller/vendor/google.golang.org/protobuf/types/descriptorpb/descriptor.pb.go b/go-controller/vendor/google.golang.org/protobuf/types/descriptorpb/descriptor.pb.go index 6dea75cd5b..a516337674 100644 --- a/go-controller/vendor/google.golang.org/protobuf/types/descriptorpb/descriptor.pb.go +++ b/go-controller/vendor/google.golang.org/protobuf/types/descriptorpb/descriptor.pb.go @@ -46,6 +46,7 @@ import ( protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + unsafe "unsafe" ) // The full set of known editions. @@ -69,7 +70,7 @@ const ( Edition_EDITION_2023 Edition = 1000 Edition_EDITION_2024 Edition = 1001 // Placeholder editions for testing feature resolution. These should not be - // used or relyed on outside of tests. + // used or relied on outside of tests. Edition_EDITION_1_TEST_ONLY Edition = 1 Edition_EDITION_2_TEST_ONLY Edition = 2 Edition_EDITION_99997_TEST_ONLY Edition = 99997 @@ -577,8 +578,6 @@ func (FieldOptions_JSType) EnumDescriptor() ([]byte, []int) { } // If set to RETENTION_SOURCE, the option will be omitted from the binary. -// Note: as of January 2023, support for this is in progress and does not yet -// have an effect (b/264593489). type FieldOptions_OptionRetention int32 const ( @@ -640,8 +639,7 @@ func (FieldOptions_OptionRetention) EnumDescriptor() ([]byte, []int) { // This indicates the types of entities that the field may apply to when used // as an option. If it is unset, then the field may be freely used as an -// option on any kind of entity. Note: as of January 2023, support for this is -// in progress and does not yet have an effect (b/264593489). +// option on any kind of entity. type FieldOptions_OptionTargetType int32 const ( @@ -1208,11 +1206,11 @@ func (GeneratedCodeInfo_Annotation_Semantic) EnumDescriptor() ([]byte, []int) { // The protocol compiler can output a FileDescriptorSet containing the .proto // files it parses. type FileDescriptorSet struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - File []*FileDescriptorProto `protobuf:"bytes,1,rep,name=file" json:"file,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + File []*FileDescriptorProto `protobuf:"bytes,1,rep,name=file" json:"file,omitempty"` + extensionFields protoimpl.ExtensionFields + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *FileDescriptorSet) Reset() { @@ -1254,12 +1252,9 @@ func (x *FileDescriptorSet) GetFile() []*FileDescriptorProto { // Describes a complete .proto file. type FileDescriptorProto struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` // file name, relative to root of source tree - Package *string `protobuf:"bytes,2,opt,name=package" json:"package,omitempty"` // e.g. "foo", "foo.bar", etc. + state protoimpl.MessageState `protogen:"open.v1"` + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` // file name, relative to root of source tree + Package *string `protobuf:"bytes,2,opt,name=package" json:"package,omitempty"` // e.g. "foo", "foo.bar", etc. // Names of files imported by this file. Dependency []string `protobuf:"bytes,3,rep,name=dependency" json:"dependency,omitempty"` // Indexes of the public imported files in the dependency list above. @@ -1284,7 +1279,9 @@ type FileDescriptorProto struct { // If `edition` is present, this value must be "editions". Syntax *string `protobuf:"bytes,12,opt,name=syntax" json:"syntax,omitempty"` // The edition of the proto file. - Edition *Edition `protobuf:"varint,14,opt,name=edition,enum=google.protobuf.Edition" json:"edition,omitempty"` + Edition *Edition `protobuf:"varint,14,opt,name=edition,enum=google.protobuf.Edition" json:"edition,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *FileDescriptorProto) Reset() { @@ -1410,10 +1407,7 @@ func (x *FileDescriptorProto) GetEdition() Edition { // Describes a message type. type DescriptorProto struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` Field []*FieldDescriptorProto `protobuf:"bytes,2,rep,name=field" json:"field,omitempty"` Extension []*FieldDescriptorProto `protobuf:"bytes,6,rep,name=extension" json:"extension,omitempty"` @@ -1425,7 +1419,9 @@ type DescriptorProto struct { ReservedRange []*DescriptorProto_ReservedRange `protobuf:"bytes,9,rep,name=reserved_range,json=reservedRange" json:"reserved_range,omitempty"` // Reserved field names, which may not be used by fields in the same message. // A given name may only be reserved once. - ReservedName []string `protobuf:"bytes,10,rep,name=reserved_name,json=reservedName" json:"reserved_name,omitempty"` + ReservedName []string `protobuf:"bytes,10,rep,name=reserved_name,json=reservedName" json:"reserved_name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *DescriptorProto) Reset() { @@ -1529,11 +1525,7 @@ func (x *DescriptorProto) GetReservedName() []string { } type ExtensionRangeOptions struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - extensionFields protoimpl.ExtensionFields - + state protoimpl.MessageState `protogen:"open.v1"` // The parser stores options it doesn't recognize here. See above. UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` // For external users: DO NOT USE. We are in the process of open sourcing @@ -1545,7 +1537,10 @@ type ExtensionRangeOptions struct { // The verification state of the range. // TODO: flip the default to DECLARATION once all empty ranges // are marked as UNVERIFIED. - Verification *ExtensionRangeOptions_VerificationState `protobuf:"varint,3,opt,name=verification,enum=google.protobuf.ExtensionRangeOptions_VerificationState,def=1" json:"verification,omitempty"` + Verification *ExtensionRangeOptions_VerificationState `protobuf:"varint,3,opt,name=verification,enum=google.protobuf.ExtensionRangeOptions_VerificationState,def=1" json:"verification,omitempty"` + extensionFields protoimpl.ExtensionFields + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } // Default values for ExtensionRangeOptions fields. @@ -1613,10 +1608,7 @@ func (x *ExtensionRangeOptions) GetVerification() ExtensionRangeOptions_Verifica // Describes a field within a message. type FieldDescriptorProto struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` Number *int32 `protobuf:"varint,3,opt,name=number" json:"number,omitempty"` Label *FieldDescriptorProto_Label `protobuf:"varint,4,opt,name=label,enum=google.protobuf.FieldDescriptorProto_Label" json:"label,omitempty"` @@ -1668,6 +1660,8 @@ type FieldDescriptorProto struct { // Proto2 optional fields do not set this flag, because they already indicate // optional with `LABEL_OPTIONAL`. Proto3Optional *bool `protobuf:"varint,17,opt,name=proto3_optional,json=proto3Optional" json:"proto3_optional,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *FieldDescriptorProto) Reset() { @@ -1779,12 +1773,11 @@ func (x *FieldDescriptorProto) GetProto3Optional() bool { // Describes a oneof. type OneofDescriptorProto struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Options *OneofOptions `protobuf:"bytes,2,opt,name=options" json:"options,omitempty"` unknownFields protoimpl.UnknownFields - - Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - Options *OneofOptions `protobuf:"bytes,2,opt,name=options" json:"options,omitempty"` + sizeCache protoimpl.SizeCache } func (x *OneofDescriptorProto) Reset() { @@ -1833,10 +1826,7 @@ func (x *OneofDescriptorProto) GetOptions() *OneofOptions { // Describes an enum type. type EnumDescriptorProto struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` Value []*EnumValueDescriptorProto `protobuf:"bytes,2,rep,name=value" json:"value,omitempty"` Options *EnumOptions `protobuf:"bytes,3,opt,name=options" json:"options,omitempty"` @@ -1846,7 +1836,9 @@ type EnumDescriptorProto struct { ReservedRange []*EnumDescriptorProto_EnumReservedRange `protobuf:"bytes,4,rep,name=reserved_range,json=reservedRange" json:"reserved_range,omitempty"` // Reserved enum value names, which may not be reused. A given name may only // be reserved once. - ReservedName []string `protobuf:"bytes,5,rep,name=reserved_name,json=reservedName" json:"reserved_name,omitempty"` + ReservedName []string `protobuf:"bytes,5,rep,name=reserved_name,json=reservedName" json:"reserved_name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *EnumDescriptorProto) Reset() { @@ -1916,13 +1908,12 @@ func (x *EnumDescriptorProto) GetReservedName() []string { // Describes a value within an enum. type EnumValueDescriptorProto struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Number *int32 `protobuf:"varint,2,opt,name=number" json:"number,omitempty"` + Options *EnumValueOptions `protobuf:"bytes,3,opt,name=options" json:"options,omitempty"` unknownFields protoimpl.UnknownFields - - Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - Number *int32 `protobuf:"varint,2,opt,name=number" json:"number,omitempty"` - Options *EnumValueOptions `protobuf:"bytes,3,opt,name=options" json:"options,omitempty"` + sizeCache protoimpl.SizeCache } func (x *EnumValueDescriptorProto) Reset() { @@ -1978,13 +1969,12 @@ func (x *EnumValueDescriptorProto) GetOptions() *EnumValueOptions { // Describes a service. type ServiceDescriptorProto struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Method []*MethodDescriptorProto `protobuf:"bytes,2,rep,name=method" json:"method,omitempty"` + Options *ServiceOptions `protobuf:"bytes,3,opt,name=options" json:"options,omitempty"` unknownFields protoimpl.UnknownFields - - Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - Method []*MethodDescriptorProto `protobuf:"bytes,2,rep,name=method" json:"method,omitempty"` - Options *ServiceOptions `protobuf:"bytes,3,opt,name=options" json:"options,omitempty"` + sizeCache protoimpl.SizeCache } func (x *ServiceDescriptorProto) Reset() { @@ -2040,11 +2030,8 @@ func (x *ServiceDescriptorProto) GetOptions() *ServiceOptions { // Describes a method of a service. type MethodDescriptorProto struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` // Input and output type names. These are resolved in the same way as // FieldDescriptorProto.type_name, but must refer to a message type. InputType *string `protobuf:"bytes,2,opt,name=input_type,json=inputType" json:"input_type,omitempty"` @@ -2054,6 +2041,8 @@ type MethodDescriptorProto struct { ClientStreaming *bool `protobuf:"varint,5,opt,name=client_streaming,json=clientStreaming,def=0" json:"client_streaming,omitempty"` // Identifies if server streams multiple server messages ServerStreaming *bool `protobuf:"varint,6,opt,name=server_streaming,json=serverStreaming,def=0" json:"server_streaming,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } // Default values for MethodDescriptorProto fields. @@ -2135,11 +2124,7 @@ func (x *MethodDescriptorProto) GetServerStreaming() bool { } type FileOptions struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - extensionFields protoimpl.ExtensionFields - + state protoimpl.MessageState `protogen:"open.v1"` // Sets the Java package where classes generated from this .proto will be // placed. By default, the proto package is used, but this is often // inappropriate because proto packages do not normally start with backwards @@ -2231,6 +2216,9 @@ type FileOptions struct { // The parser stores options it doesn't recognize here. // See the documentation for the "Options" section above. UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` + extensionFields protoimpl.ExtensionFields + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } // Default values for FileOptions fields. @@ -2424,11 +2412,7 @@ func (x *FileOptions) GetUninterpretedOption() []*UninterpretedOption { } type MessageOptions struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - extensionFields protoimpl.ExtensionFields - + state protoimpl.MessageState `protogen:"open.v1"` // Set true to use the old proto1 MessageSet wire format for extensions. // This is provided for backwards-compatibility with the MessageSet wire // format. You should not use this for any other reason: It's less @@ -2501,6 +2485,9 @@ type MessageOptions struct { Features *FeatureSet `protobuf:"bytes,12,opt,name=features" json:"features,omitempty"` // The parser stores options it doesn't recognize here. See above. UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` + extensionFields protoimpl.ExtensionFields + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } // Default values for MessageOptions fields. @@ -2591,17 +2578,14 @@ func (x *MessageOptions) GetUninterpretedOption() []*UninterpretedOption { } type FieldOptions struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - extensionFields protoimpl.ExtensionFields - + state protoimpl.MessageState `protogen:"open.v1"` + // NOTE: ctype is deprecated. Use `features.(pb.cpp).string_type` instead. // The ctype option instructs the C++ code generator to use a different // representation of the field than it normally would. See the specific // options below. This option is only implemented to support use of // [ctype=CORD] and [ctype=STRING] (the default) on non-repeated fields of - // type "bytes" in the open source release -- sorry, we'll try to include - // other types in a future version! + // type "bytes" in the open source release. + // TODO: make ctype actually deprecated. Ctype *FieldOptions_CType `protobuf:"varint,1,opt,name=ctype,enum=google.protobuf.FieldOptions_CType,def=0" json:"ctype,omitempty"` // The packed option can be enabled for repeated primitive fields to enable // a more efficient representation on the wire. Rather than repeatedly @@ -2668,6 +2652,9 @@ type FieldOptions struct { FeatureSupport *FieldOptions_FeatureSupport `protobuf:"bytes,22,opt,name=feature_support,json=featureSupport" json:"feature_support,omitempty"` // The parser stores options it doesn't recognize here. See above. UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` + extensionFields protoimpl.ExtensionFields + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } // Default values for FieldOptions fields. @@ -2810,15 +2797,14 @@ func (x *FieldOptions) GetUninterpretedOption() []*UninterpretedOption { } type OneofOptions struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - extensionFields protoimpl.ExtensionFields - + state protoimpl.MessageState `protogen:"open.v1"` // Any features defined in the specific edition. Features *FeatureSet `protobuf:"bytes,1,opt,name=features" json:"features,omitempty"` // The parser stores options it doesn't recognize here. See above. UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` + extensionFields protoimpl.ExtensionFields + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *OneofOptions) Reset() { @@ -2866,11 +2852,7 @@ func (x *OneofOptions) GetUninterpretedOption() []*UninterpretedOption { } type EnumOptions struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - extensionFields protoimpl.ExtensionFields - + state protoimpl.MessageState `protogen:"open.v1"` // Set this option to true to allow mapping different tag names to the same // value. AllowAlias *bool `protobuf:"varint,2,opt,name=allow_alias,json=allowAlias" json:"allow_alias,omitempty"` @@ -2892,6 +2874,9 @@ type EnumOptions struct { Features *FeatureSet `protobuf:"bytes,7,opt,name=features" json:"features,omitempty"` // The parser stores options it doesn't recognize here. See above. UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` + extensionFields protoimpl.ExtensionFields + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } // Default values for EnumOptions fields. @@ -2966,11 +2951,7 @@ func (x *EnumOptions) GetUninterpretedOption() []*UninterpretedOption { } type EnumValueOptions struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - extensionFields protoimpl.ExtensionFields - + state protoimpl.MessageState `protogen:"open.v1"` // Is this enum value deprecated? // Depending on the target platform, this can emit Deprecated annotations // for the enum value, or it will be completely ignored; in the very least, @@ -2986,6 +2967,9 @@ type EnumValueOptions struct { FeatureSupport *FieldOptions_FeatureSupport `protobuf:"bytes,4,opt,name=feature_support,json=featureSupport" json:"feature_support,omitempty"` // The parser stores options it doesn't recognize here. See above. UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` + extensionFields protoimpl.ExtensionFields + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } // Default values for EnumValueOptions fields. @@ -3060,11 +3044,7 @@ func (x *EnumValueOptions) GetUninterpretedOption() []*UninterpretedOption { } type ServiceOptions struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - extensionFields protoimpl.ExtensionFields - + state protoimpl.MessageState `protogen:"open.v1"` // Any features defined in the specific edition. Features *FeatureSet `protobuf:"bytes,34,opt,name=features" json:"features,omitempty"` // Is this service deprecated? @@ -3074,6 +3054,9 @@ type ServiceOptions struct { Deprecated *bool `protobuf:"varint,33,opt,name=deprecated,def=0" json:"deprecated,omitempty"` // The parser stores options it doesn't recognize here. See above. UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` + extensionFields protoimpl.ExtensionFields + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } // Default values for ServiceOptions fields. @@ -3133,11 +3116,7 @@ func (x *ServiceOptions) GetUninterpretedOption() []*UninterpretedOption { } type MethodOptions struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - extensionFields protoimpl.ExtensionFields - + state protoimpl.MessageState `protogen:"open.v1"` // Is this method deprecated? // Depending on the target platform, this can emit Deprecated annotations // for the method, or it will be completely ignored; in the very least, @@ -3148,6 +3127,9 @@ type MethodOptions struct { Features *FeatureSet `protobuf:"bytes,35,opt,name=features" json:"features,omitempty"` // The parser stores options it doesn't recognize here. See above. UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` + extensionFields protoimpl.ExtensionFields + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } // Default values for MethodOptions fields. @@ -3221,11 +3203,8 @@ func (x *MethodOptions) GetUninterpretedOption() []*UninterpretedOption { // or produced by Descriptor::CopyTo()) will never have UninterpretedOptions // in them. type UninterpretedOption struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name []*UninterpretedOption_NamePart `protobuf:"bytes,2,rep,name=name" json:"name,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + Name []*UninterpretedOption_NamePart `protobuf:"bytes,2,rep,name=name" json:"name,omitempty"` // The value of the uninterpreted option, in whatever type the tokenizer // identified it as during parsing. Exactly one of these should be set. IdentifierValue *string `protobuf:"bytes,3,opt,name=identifier_value,json=identifierValue" json:"identifier_value,omitempty"` @@ -3234,6 +3213,8 @@ type UninterpretedOption struct { DoubleValue *float64 `protobuf:"fixed64,6,opt,name=double_value,json=doubleValue" json:"double_value,omitempty"` StringValue []byte `protobuf:"bytes,7,opt,name=string_value,json=stringValue" json:"string_value,omitempty"` AggregateValue *string `protobuf:"bytes,8,opt,name=aggregate_value,json=aggregateValue" json:"aggregate_value,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *UninterpretedOption) Reset() { @@ -3322,17 +3303,16 @@ func (x *UninterpretedOption) GetAggregateValue() string { // be designed and implemented to handle this, hopefully before we ever hit a // conflict here. type FeatureSet struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - extensionFields protoimpl.ExtensionFields - + state protoimpl.MessageState `protogen:"open.v1"` FieldPresence *FeatureSet_FieldPresence `protobuf:"varint,1,opt,name=field_presence,json=fieldPresence,enum=google.protobuf.FeatureSet_FieldPresence" json:"field_presence,omitempty"` EnumType *FeatureSet_EnumType `protobuf:"varint,2,opt,name=enum_type,json=enumType,enum=google.protobuf.FeatureSet_EnumType" json:"enum_type,omitempty"` RepeatedFieldEncoding *FeatureSet_RepeatedFieldEncoding `protobuf:"varint,3,opt,name=repeated_field_encoding,json=repeatedFieldEncoding,enum=google.protobuf.FeatureSet_RepeatedFieldEncoding" json:"repeated_field_encoding,omitempty"` Utf8Validation *FeatureSet_Utf8Validation `protobuf:"varint,4,opt,name=utf8_validation,json=utf8Validation,enum=google.protobuf.FeatureSet_Utf8Validation" json:"utf8_validation,omitempty"` MessageEncoding *FeatureSet_MessageEncoding `protobuf:"varint,5,opt,name=message_encoding,json=messageEncoding,enum=google.protobuf.FeatureSet_MessageEncoding" json:"message_encoding,omitempty"` JsonFormat *FeatureSet_JsonFormat `protobuf:"varint,6,opt,name=json_format,json=jsonFormat,enum=google.protobuf.FeatureSet_JsonFormat" json:"json_format,omitempty"` + extensionFields protoimpl.ExtensionFields + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *FeatureSet) Reset() { @@ -3412,10 +3392,7 @@ func (x *FeatureSet) GetJsonFormat() FeatureSet_JsonFormat { // feature resolution. The resolution with this object becomes a simple search // for the closest matching edition, followed by proto merges. type FeatureSetDefaults struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` Defaults []*FeatureSetDefaults_FeatureSetEditionDefault `protobuf:"bytes,1,rep,name=defaults" json:"defaults,omitempty"` // The minimum supported edition (inclusive) when this was constructed. // Editions before this will not have defaults. @@ -3423,6 +3400,8 @@ type FeatureSetDefaults struct { // The maximum known edition (inclusive) when this was constructed. Editions // after this will not have reliable defaults. MaximumEdition *Edition `protobuf:"varint,5,opt,name=maximum_edition,json=maximumEdition,enum=google.protobuf.Edition" json:"maximum_edition,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *FeatureSetDefaults) Reset() { @@ -3479,10 +3458,7 @@ func (x *FeatureSetDefaults) GetMaximumEdition() Edition { // Encapsulates information about the original source file from which a // FileDescriptorProto was generated. type SourceCodeInfo struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` // A Location identifies a piece of source code in a .proto file which // corresponds to a particular definition. This information is intended // to be useful to IDEs, code indexers, documentation generators, and similar @@ -3531,7 +3507,10 @@ type SourceCodeInfo struct { // - Code which tries to interpret locations should probably be designed to // ignore those that it doesn't understand, as more types of locations could // be recorded in the future. - Location []*SourceCodeInfo_Location `protobuf:"bytes,1,rep,name=location" json:"location,omitempty"` + Location []*SourceCodeInfo_Location `protobuf:"bytes,1,rep,name=location" json:"location,omitempty"` + extensionFields protoimpl.ExtensionFields + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *SourceCodeInfo) Reset() { @@ -3575,13 +3554,12 @@ func (x *SourceCodeInfo) GetLocation() []*SourceCodeInfo_Location { // file. A GeneratedCodeInfo message is associated with only one generated // source file, but may contain references to different source .proto files. type GeneratedCodeInfo struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` // An Annotation connects some span of text in generated code to an element // of its generating .proto file. - Annotation []*GeneratedCodeInfo_Annotation `protobuf:"bytes,1,rep,name=annotation" json:"annotation,omitempty"` + Annotation []*GeneratedCodeInfo_Annotation `protobuf:"bytes,1,rep,name=annotation" json:"annotation,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *GeneratedCodeInfo) Reset() { @@ -3622,13 +3600,12 @@ func (x *GeneratedCodeInfo) GetAnnotation() []*GeneratedCodeInfo_Annotation { } type DescriptorProto_ExtensionRange struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Start *int32 `protobuf:"varint,1,opt,name=start" json:"start,omitempty"` // Inclusive. + End *int32 `protobuf:"varint,2,opt,name=end" json:"end,omitempty"` // Exclusive. + Options *ExtensionRangeOptions `protobuf:"bytes,3,opt,name=options" json:"options,omitempty"` unknownFields protoimpl.UnknownFields - - Start *int32 `protobuf:"varint,1,opt,name=start" json:"start,omitempty"` // Inclusive. - End *int32 `protobuf:"varint,2,opt,name=end" json:"end,omitempty"` // Exclusive. - Options *ExtensionRangeOptions `protobuf:"bytes,3,opt,name=options" json:"options,omitempty"` + sizeCache protoimpl.SizeCache } func (x *DescriptorProto_ExtensionRange) Reset() { @@ -3686,12 +3663,11 @@ func (x *DescriptorProto_ExtensionRange) GetOptions() *ExtensionRangeOptions { // fields or extension ranges in the same message. Reserved ranges may // not overlap. type DescriptorProto_ReservedRange struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Start *int32 `protobuf:"varint,1,opt,name=start" json:"start,omitempty"` // Inclusive. + End *int32 `protobuf:"varint,2,opt,name=end" json:"end,omitempty"` // Exclusive. unknownFields protoimpl.UnknownFields - - Start *int32 `protobuf:"varint,1,opt,name=start" json:"start,omitempty"` // Inclusive. - End *int32 `protobuf:"varint,2,opt,name=end" json:"end,omitempty"` // Exclusive. + sizeCache protoimpl.SizeCache } func (x *DescriptorProto_ReservedRange) Reset() { @@ -3739,10 +3715,7 @@ func (x *DescriptorProto_ReservedRange) GetEnd() int32 { } type ExtensionRangeOptions_Declaration struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` // The extension number declared within the extension range. Number *int32 `protobuf:"varint,1,opt,name=number" json:"number,omitempty"` // The fully-qualified name of the extension field. There must be a leading @@ -3758,7 +3731,9 @@ type ExtensionRangeOptions_Declaration struct { Reserved *bool `protobuf:"varint,5,opt,name=reserved" json:"reserved,omitempty"` // If true, indicates that the extension must be defined as repeated. // Otherwise the extension must be defined as optional. - Repeated *bool `protobuf:"varint,6,opt,name=repeated" json:"repeated,omitempty"` + Repeated *bool `protobuf:"varint,6,opt,name=repeated" json:"repeated,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *ExtensionRangeOptions_Declaration) Reset() { @@ -3833,12 +3808,11 @@ func (x *ExtensionRangeOptions_Declaration) GetRepeated() bool { // is inclusive such that it can appropriately represent the entire int32 // domain. type EnumDescriptorProto_EnumReservedRange struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Start *int32 `protobuf:"varint,1,opt,name=start" json:"start,omitempty"` // Inclusive. + End *int32 `protobuf:"varint,2,opt,name=end" json:"end,omitempty"` // Inclusive. unknownFields protoimpl.UnknownFields - - Start *int32 `protobuf:"varint,1,opt,name=start" json:"start,omitempty"` // Inclusive. - End *int32 `protobuf:"varint,2,opt,name=end" json:"end,omitempty"` // Inclusive. + sizeCache protoimpl.SizeCache } func (x *EnumDescriptorProto_EnumReservedRange) Reset() { @@ -3886,12 +3860,11 @@ func (x *EnumDescriptorProto_EnumReservedRange) GetEnd() int32 { } type FieldOptions_EditionDefault struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Edition *Edition `protobuf:"varint,3,opt,name=edition,enum=google.protobuf.Edition" json:"edition,omitempty"` + Value *string `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"` // Textproto value. unknownFields protoimpl.UnknownFields - - Edition *Edition `protobuf:"varint,3,opt,name=edition,enum=google.protobuf.Edition" json:"edition,omitempty"` - Value *string `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"` // Textproto value. + sizeCache protoimpl.SizeCache } func (x *FieldOptions_EditionDefault) Reset() { @@ -3940,10 +3913,7 @@ func (x *FieldOptions_EditionDefault) GetValue() string { // Information about the support window of a feature. type FieldOptions_FeatureSupport struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` // The edition that this feature was first available in. In editions // earlier than this one, the default assigned to EDITION_LEGACY will be // used, and proto files will not be able to override it. @@ -3958,6 +3928,8 @@ type FieldOptions_FeatureSupport struct { // this one, the last default assigned will be used, and proto files will // not be able to override it. EditionRemoved *Edition `protobuf:"varint,4,opt,name=edition_removed,json=editionRemoved,enum=google.protobuf.Edition" json:"edition_removed,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *FieldOptions_FeatureSupport) Reset() { @@ -4024,12 +3996,11 @@ func (x *FieldOptions_FeatureSupport) GetEditionRemoved() Edition { // E.g.,{ ["foo", false], ["bar.baz", true], ["moo", false] } represents // "foo.(bar.baz).moo". type UninterpretedOption_NamePart struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + NamePart *string `protobuf:"bytes,1,req,name=name_part,json=namePart" json:"name_part,omitempty"` + IsExtension *bool `protobuf:"varint,2,req,name=is_extension,json=isExtension" json:"is_extension,omitempty"` unknownFields protoimpl.UnknownFields - - NamePart *string `protobuf:"bytes,1,req,name=name_part,json=namePart" json:"name_part,omitempty"` - IsExtension *bool `protobuf:"varint,2,req,name=is_extension,json=isExtension" json:"is_extension,omitempty"` + sizeCache protoimpl.SizeCache } func (x *UninterpretedOption_NamePart) Reset() { @@ -4081,15 +4052,14 @@ func (x *UninterpretedOption_NamePart) GetIsExtension() bool { // the defaults at the closest matching edition ordered at or before it should // be used. This field must be in strict ascending order by edition. type FeatureSetDefaults_FeatureSetEditionDefault struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Edition *Edition `protobuf:"varint,3,opt,name=edition,enum=google.protobuf.Edition" json:"edition,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + Edition *Edition `protobuf:"varint,3,opt,name=edition,enum=google.protobuf.Edition" json:"edition,omitempty"` // Defaults of features that can be overridden in this edition. OverridableFeatures *FeatureSet `protobuf:"bytes,4,opt,name=overridable_features,json=overridableFeatures" json:"overridable_features,omitempty"` // Defaults of features that can't be overridden in this edition. FixedFeatures *FeatureSet `protobuf:"bytes,5,opt,name=fixed_features,json=fixedFeatures" json:"fixed_features,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *FeatureSetDefaults_FeatureSetEditionDefault) Reset() { @@ -4144,10 +4114,7 @@ func (x *FeatureSetDefaults_FeatureSetEditionDefault) GetFixedFeatures() *Featur } type SourceCodeInfo_Location struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` // Identifies which part of the FileDescriptorProto was defined at this // location. // @@ -4239,6 +4206,8 @@ type SourceCodeInfo_Location struct { LeadingComments *string `protobuf:"bytes,3,opt,name=leading_comments,json=leadingComments" json:"leading_comments,omitempty"` TrailingComments *string `protobuf:"bytes,4,opt,name=trailing_comments,json=trailingComments" json:"trailing_comments,omitempty"` LeadingDetachedComments []string `protobuf:"bytes,6,rep,name=leading_detached_comments,json=leadingDetachedComments" json:"leading_detached_comments,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *SourceCodeInfo_Location) Reset() { @@ -4307,10 +4276,7 @@ func (x *SourceCodeInfo_Location) GetLeadingDetachedComments() []string { } type GeneratedCodeInfo_Annotation struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` // Identifies the element in the original source .proto file. This field // is formatted the same as SourceCodeInfo.Location.path. Path []int32 `protobuf:"varint,1,rep,packed,name=path" json:"path,omitempty"` @@ -4322,8 +4288,10 @@ type GeneratedCodeInfo_Annotation struct { // Identifies the ending offset in bytes in the generated code that // relates to the identified object. The end offset should be one past // the last relevant byte (so the length of the text = end - begin). - End *int32 `protobuf:"varint,4,opt,name=end" json:"end,omitempty"` - Semantic *GeneratedCodeInfo_Annotation_Semantic `protobuf:"varint,5,opt,name=semantic,enum=google.protobuf.GeneratedCodeInfo_Annotation_Semantic" json:"semantic,omitempty"` + End *int32 `protobuf:"varint,4,opt,name=end" json:"end,omitempty"` + Semantic *GeneratedCodeInfo_Annotation_Semantic `protobuf:"varint,5,opt,name=semantic,enum=google.protobuf.GeneratedCodeInfo_Annotation_Semantic" json:"semantic,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *GeneratedCodeInfo_Annotation) Reset() { @@ -4393,498 +4361,478 @@ func (x *GeneratedCodeInfo_Annotation) GetSemantic() GeneratedCodeInfo_Annotatio var File_google_protobuf_descriptor_proto protoreflect.FileDescriptor -var file_google_protobuf_descriptor_proto_rawDesc = []byte{ +var file_google_protobuf_descriptor_proto_rawDesc = string([]byte{ 0x0a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x22, 0x4d, 0x0a, 0x11, 0x46, 0x69, 0x6c, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, + 0x62, 0x75, 0x66, 0x22, 0x5b, 0x0a, 0x11, 0x46, 0x69, 0x6c, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x53, 0x65, 0x74, 0x12, 0x38, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x52, 0x04, 0x66, 0x69, - 0x6c, 0x65, 0x22, 0x98, 0x05, 0x0a, 0x13, 0x46, 0x69, 0x6c, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, - 0x0a, 0x07, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x65, - 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x65, - 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x2b, 0x0a, 0x11, 0x70, 0x75, 0x62, 0x6c, - 0x69, 0x63, 0x5f, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x0a, 0x20, - 0x03, 0x28, 0x05, 0x52, 0x10, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x44, 0x65, 0x70, 0x65, 0x6e, - 0x64, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x27, 0x0a, 0x0f, 0x77, 0x65, 0x61, 0x6b, 0x5f, 0x64, 0x65, - 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x05, 0x52, 0x0e, - 0x77, 0x65, 0x61, 0x6b, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x43, - 0x0a, 0x0c, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, - 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x52, 0x0b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, - 0x79, 0x70, 0x65, 0x12, 0x41, 0x0a, 0x09, 0x65, 0x6e, 0x75, 0x6d, 0x5f, 0x74, 0x79, 0x70, 0x65, - 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x44, 0x65, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x52, 0x08, 0x65, 0x6e, - 0x75, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x12, 0x41, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, - 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x43, 0x0a, 0x09, 0x65, 0x78, 0x74, - 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, - 0x69, 0x65, 0x6c, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, - 0x6f, 0x74, 0x6f, 0x52, 0x09, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x36, - 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x49, 0x0a, 0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, - 0x6f, 0x52, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, - 0x6f, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x18, 0x0c, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x12, 0x32, 0x0a, 0x07, 0x65, 0x64, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x64, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x65, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xb9, 0x06, - 0x0a, 0x0f, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3b, 0x0a, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x44, 0x65, 0x73, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x52, 0x05, 0x66, 0x69, 0x65, - 0x6c, 0x64, 0x12, 0x43, 0x0a, 0x09, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, - 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x44, 0x65, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x52, 0x09, 0x65, 0x78, - 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x41, 0x0a, 0x0b, 0x6e, 0x65, 0x73, 0x74, 0x65, - 0x64, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x52, 0x0a, - 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, 0x12, 0x41, 0x0a, 0x09, 0x65, 0x6e, - 0x75, 0x6d, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, + 0x6c, 0x65, 0x2a, 0x0c, 0x08, 0x80, 0xec, 0xca, 0xff, 0x01, 0x10, 0x81, 0xec, 0xca, 0xff, 0x01, + 0x22, 0x98, 0x05, 0x0a, 0x13, 0x46, 0x69, 0x6c, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, + 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, + 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, + 0x65, 0x6e, 0x63, 0x79, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x65, + 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x2b, 0x0a, 0x11, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x5f, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x0a, 0x20, 0x03, 0x28, + 0x05, 0x52, 0x10, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, + 0x6e, 0x63, 0x79, 0x12, 0x27, 0x0a, 0x0f, 0x77, 0x65, 0x61, 0x6b, 0x5f, 0x64, 0x65, 0x70, 0x65, + 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x05, 0x52, 0x0e, 0x77, 0x65, + 0x61, 0x6b, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x43, 0x0a, 0x0c, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, + 0x72, 0x6f, 0x74, 0x6f, 0x52, 0x0b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x41, 0x0a, 0x09, 0x65, 0x6e, 0x75, 0x6d, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x44, 0x65, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x52, 0x08, 0x65, 0x6e, 0x75, 0x6d, + 0x54, 0x79, 0x70, 0x65, 0x12, 0x41, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, + 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x52, 0x07, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x43, 0x0a, 0x09, 0x65, 0x78, 0x74, 0x65, 0x6e, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, + 0x6c, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x52, 0x09, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x36, 0x0a, 0x07, + 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x45, 0x6e, 0x75, 0x6d, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, - 0x6f, 0x74, 0x6f, 0x52, 0x08, 0x65, 0x6e, 0x75, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x12, 0x58, 0x0a, - 0x0f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, - 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, - 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, - 0x6f, 0x6e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x0e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, - 0x6f, 0x6e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x44, 0x0a, 0x0a, 0x6f, 0x6e, 0x65, 0x6f, 0x66, - 0x5f, 0x64, 0x65, 0x63, 0x6c, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4f, 0x6e, - 0x65, 0x6f, 0x66, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x52, 0x09, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x44, 0x65, 0x63, 0x6c, 0x12, 0x39, 0x0a, - 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, + 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x49, 0x0a, 0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x63, + 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, - 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x55, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x64, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x2e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x61, 0x6e, 0x67, 0x65, - 0x52, 0x0d, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, - 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, - 0x4e, 0x61, 0x6d, 0x65, 0x1a, 0x7a, 0x0a, 0x0e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, - 0x6e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, - 0x65, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x12, 0x40, - 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x26, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x61, 0x6e, 0x67, 0x65, - 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x1a, 0x37, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x61, 0x6e, 0x67, - 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x22, 0xcc, 0x04, 0x0a, 0x15, 0x45, 0x78, - 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x12, 0x58, 0x0a, 0x14, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, - 0x65, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xe7, 0x07, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, - 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x59, 0x0a, - 0x0b, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x61, - 0x6e, 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x44, 0x65, 0x63, 0x6c, 0x61, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x03, 0x88, 0x01, 0x02, 0x52, 0x0b, 0x64, 0x65, 0x63, - 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x37, 0x0a, 0x08, 0x66, 0x65, 0x61, 0x74, - 0x75, 0x72, 0x65, 0x73, 0x18, 0x32, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x65, 0x61, - 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x52, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, - 0x73, 0x12, 0x6d, 0x0a, 0x0c, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x38, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, - 0x69, 0x6f, 0x6e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, - 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x3a, 0x0a, 0x55, 0x4e, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x42, 0x03, 0x88, - 0x01, 0x02, 0x52, 0x0c, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x1a, 0x94, 0x01, 0x0a, 0x0b, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x75, 0x6c, 0x6c, - 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x75, 0x6c, - 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, - 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, - 0x64, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x22, 0x34, 0x0a, 0x11, 0x56, 0x65, 0x72, 0x69, 0x66, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0f, 0x0a, 0x0b, - 0x44, 0x45, 0x43, 0x4c, 0x41, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x00, 0x12, 0x0e, 0x0a, - 0x0a, 0x55, 0x4e, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x01, 0x2a, 0x09, 0x08, - 0xe8, 0x07, 0x10, 0x80, 0x80, 0x80, 0x80, 0x02, 0x22, 0xc1, 0x06, 0x0a, 0x14, 0x46, 0x69, 0x65, + 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, + 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, + 0x16, 0x0a, 0x06, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x12, 0x32, 0x0a, 0x07, 0x65, 0x64, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x64, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x07, 0x65, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xb9, 0x06, 0x0a, 0x0f, + 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x3b, 0x0a, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x52, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, + 0x12, 0x43, 0x0a, 0x09, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x52, 0x09, 0x65, 0x78, 0x74, 0x65, + 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x41, 0x0a, 0x0b, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x65, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x52, 0x0a, 0x6e, 0x65, + 0x73, 0x74, 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, 0x12, 0x41, 0x0a, 0x09, 0x65, 0x6e, 0x75, 0x6d, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, + 0x75, 0x6d, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x52, 0x08, 0x65, 0x6e, 0x75, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x12, 0x58, 0x0a, 0x0f, 0x65, + 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x05, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, + 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, + 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x0e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, + 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x44, 0x0a, 0x0a, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x5f, 0x64, + 0x65, 0x63, 0x6c, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4f, 0x6e, 0x65, 0x6f, + 0x66, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, + 0x52, 0x09, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x44, 0x65, 0x63, 0x6c, 0x12, 0x39, 0x0a, 0x07, 0x6f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x55, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x64, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x0d, + 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x23, 0x0a, + 0x0d, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0a, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x4e, 0x61, + 0x6d, 0x65, 0x1a, 0x7a, 0x0a, 0x0e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, + 0x61, 0x6e, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x12, 0x40, 0x0a, 0x07, + 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x4f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x37, + 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, + 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, + 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x22, 0xcc, 0x04, 0x0a, 0x15, 0x45, 0x78, 0x74, 0x65, + 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0x58, 0x0a, 0x14, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, + 0x65, 0x64, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xe7, 0x07, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, + 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x59, 0x0a, 0x0b, 0x64, + 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x32, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x61, 0x6e, 0x67, + 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x03, 0x88, 0x01, 0x02, 0x52, 0x0b, 0x64, 0x65, 0x63, 0x6c, 0x61, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x37, 0x0a, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x73, 0x18, 0x32, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x53, 0x65, 0x74, 0x52, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, + 0x6d, 0x0a, 0x0c, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x38, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, + 0x6e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x56, 0x65, + 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x3a, + 0x0a, 0x55, 0x4e, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x42, 0x03, 0x88, 0x01, 0x02, + 0x52, 0x0c, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x94, + 0x01, 0x0a, 0x0b, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, + 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, + 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x75, 0x6c, 0x6c, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x75, 0x6c, 0x6c, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x4a, + 0x04, 0x08, 0x04, 0x10, 0x05, 0x22, 0x34, 0x0a, 0x11, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x44, 0x45, + 0x43, 0x4c, 0x41, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x55, + 0x4e, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x01, 0x2a, 0x09, 0x08, 0xe8, 0x07, + 0x10, 0x80, 0x80, 0x80, 0x80, 0x02, 0x22, 0xc1, 0x06, 0x0a, 0x14, 0x46, 0x69, 0x65, 0x6c, 0x64, + 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x41, 0x0a, 0x05, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x41, 0x0a, - 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x67, + 0x6f, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x3e, + 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, - 0x12, 0x3e, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, - 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, - 0x08, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x65, 0x66, - 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0c, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1f, - 0x0a, 0x0b, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x09, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x0a, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, - 0x1b, 0x0a, 0x09, 0x6a, 0x73, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x6a, 0x73, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x37, 0x0a, 0x07, - 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, + 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1b, + 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x65, + 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, + 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x65, 0x66, 0x61, 0x75, + 0x6c, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, + 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1f, 0x0a, 0x0b, + 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x09, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x0a, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x1b, 0x0a, + 0x09, 0x6a, 0x73, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x6a, 0x73, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x37, 0x0a, 0x07, 0x6f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, + 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x5f, 0x6f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x22, 0xb6, 0x02, 0x0a, + 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x4f, + 0x55, 0x42, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, + 0x4c, 0x4f, 0x41, 0x54, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, + 0x4e, 0x54, 0x36, 0x34, 0x10, 0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, + 0x49, 0x4e, 0x54, 0x36, 0x34, 0x10, 0x04, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x59, 0x50, 0x45, 0x5f, + 0x49, 0x4e, 0x54, 0x33, 0x32, 0x10, 0x05, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x59, 0x50, 0x45, 0x5f, + 0x46, 0x49, 0x58, 0x45, 0x44, 0x36, 0x34, 0x10, 0x06, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x59, 0x50, + 0x45, 0x5f, 0x46, 0x49, 0x58, 0x45, 0x44, 0x33, 0x32, 0x10, 0x07, 0x12, 0x0d, 0x0a, 0x09, 0x54, + 0x59, 0x50, 0x45, 0x5f, 0x42, 0x4f, 0x4f, 0x4c, 0x10, 0x08, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x59, + 0x50, 0x45, 0x5f, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x09, 0x12, 0x0e, 0x0a, 0x0a, 0x54, + 0x59, 0x50, 0x45, 0x5f, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x10, 0x0a, 0x12, 0x10, 0x0a, 0x0c, 0x54, + 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x10, 0x0b, 0x12, 0x0e, 0x0a, + 0x0a, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, 0x59, 0x54, 0x45, 0x53, 0x10, 0x0c, 0x12, 0x0f, 0x0a, + 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x49, 0x4e, 0x54, 0x33, 0x32, 0x10, 0x0d, 0x12, 0x0d, + 0x0a, 0x09, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x10, 0x0e, 0x12, 0x11, 0x0a, + 0x0d, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x46, 0x49, 0x58, 0x45, 0x44, 0x33, 0x32, 0x10, 0x0f, + 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x46, 0x49, 0x58, 0x45, 0x44, 0x36, + 0x34, 0x10, 0x10, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x49, 0x4e, 0x54, + 0x33, 0x32, 0x10, 0x11, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x49, 0x4e, + 0x54, 0x36, 0x34, 0x10, 0x12, 0x22, 0x43, 0x0a, 0x05, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x12, + 0x0a, 0x0e, 0x4c, 0x41, 0x42, 0x45, 0x4c, 0x5f, 0x4f, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x41, 0x4c, + 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x4c, 0x41, 0x42, 0x45, 0x4c, 0x5f, 0x52, 0x45, 0x50, 0x45, + 0x41, 0x54, 0x45, 0x44, 0x10, 0x03, 0x12, 0x12, 0x0a, 0x0e, 0x4c, 0x41, 0x42, 0x45, 0x4c, 0x5f, + 0x52, 0x45, 0x51, 0x55, 0x49, 0x52, 0x45, 0x44, 0x10, 0x02, 0x22, 0x63, 0x0a, 0x14, 0x4f, 0x6e, + 0x65, 0x6f, 0x66, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, + 0x74, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x37, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4f, 0x6e, 0x65, 0x6f, 0x66, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, + 0xe3, 0x02, 0x0a, 0x13, 0x45, 0x6e, 0x75, 0x6d, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3f, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, + 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x36, 0x0a, 0x07, + 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x5f, - 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x22, 0xb6, - 0x02, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f, - 0x44, 0x4f, 0x55, 0x42, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x46, 0x4c, 0x4f, 0x41, 0x54, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x49, 0x4e, 0x54, 0x36, 0x34, 0x10, 0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x55, 0x49, 0x4e, 0x54, 0x36, 0x34, 0x10, 0x04, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x59, 0x50, - 0x45, 0x5f, 0x49, 0x4e, 0x54, 0x33, 0x32, 0x10, 0x05, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x59, 0x50, - 0x45, 0x5f, 0x46, 0x49, 0x58, 0x45, 0x44, 0x36, 0x34, 0x10, 0x06, 0x12, 0x10, 0x0a, 0x0c, 0x54, - 0x59, 0x50, 0x45, 0x5f, 0x46, 0x49, 0x58, 0x45, 0x44, 0x33, 0x32, 0x10, 0x07, 0x12, 0x0d, 0x0a, - 0x09, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, 0x4f, 0x4f, 0x4c, 0x10, 0x08, 0x12, 0x0f, 0x0a, 0x0b, - 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x09, 0x12, 0x0e, 0x0a, - 0x0a, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x10, 0x0a, 0x12, 0x10, 0x0a, - 0x0c, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x10, 0x0b, 0x12, - 0x0e, 0x0a, 0x0a, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, 0x59, 0x54, 0x45, 0x53, 0x10, 0x0c, 0x12, - 0x0f, 0x0a, 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x49, 0x4e, 0x54, 0x33, 0x32, 0x10, 0x0d, - 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x10, 0x0e, 0x12, - 0x11, 0x0a, 0x0d, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x46, 0x49, 0x58, 0x45, 0x44, 0x33, 0x32, - 0x10, 0x0f, 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x46, 0x49, 0x58, 0x45, - 0x44, 0x36, 0x34, 0x10, 0x10, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x49, - 0x4e, 0x54, 0x33, 0x32, 0x10, 0x11, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, - 0x49, 0x4e, 0x54, 0x36, 0x34, 0x10, 0x12, 0x22, 0x43, 0x0a, 0x05, 0x4c, 0x61, 0x62, 0x65, 0x6c, - 0x12, 0x12, 0x0a, 0x0e, 0x4c, 0x41, 0x42, 0x45, 0x4c, 0x5f, 0x4f, 0x50, 0x54, 0x49, 0x4f, 0x4e, - 0x41, 0x4c, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x4c, 0x41, 0x42, 0x45, 0x4c, 0x5f, 0x52, 0x45, - 0x50, 0x45, 0x41, 0x54, 0x45, 0x44, 0x10, 0x03, 0x12, 0x12, 0x0a, 0x0e, 0x4c, 0x41, 0x42, 0x45, - 0x4c, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x49, 0x52, 0x45, 0x44, 0x10, 0x02, 0x22, 0x63, 0x0a, 0x14, - 0x4f, 0x6e, 0x65, 0x6f, 0x66, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x37, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4f, 0x6e, 0x65, 0x6f, - 0x66, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x22, 0xe3, 0x02, 0x0a, 0x13, 0x45, 0x6e, 0x75, 0x6d, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3f, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x67, + 0x45, 0x6e, 0x75, 0x6d, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x5d, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, + 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, - 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x36, + 0x6e, 0x75, 0x6d, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, + 0x61, 0x6e, 0x67, 0x65, 0x52, 0x0d, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x61, + 0x6e, 0x67, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x1a, 0x3b, 0x0a, 0x11, 0x45, 0x6e, 0x75, 0x6d, + 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x14, 0x0a, + 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x03, 0x65, 0x6e, 0x64, 0x22, 0x83, 0x01, 0x0a, 0x18, 0x45, 0x6e, 0x75, 0x6d, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, + 0x74, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x3b, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x5d, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x64, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x64, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x0d, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, - 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x1a, 0x3b, 0x0a, 0x11, 0x45, 0x6e, - 0x75, 0x6d, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, - 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, - 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x05, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x22, 0x83, 0x01, 0x0a, 0x18, 0x45, 0x6e, 0x75, 0x6d, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, - 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, - 0x12, 0x3b, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x21, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xa7, 0x01, - 0x0a, 0x16, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, - 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x06, - 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, - 0x65, 0x74, 0x68, 0x6f, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x39, 0x0a, 0x07, - 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, + 0x21, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xa7, 0x01, 0x0a, 0x16, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, + 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x06, 0x6d, 0x65, + 0x74, 0x68, 0x6f, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, + 0x68, 0x6f, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, + 0x74, 0x6f, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x39, 0x0a, 0x07, 0x6f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x89, 0x02, 0x0a, 0x15, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, + 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x38, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x30, 0x0a, + 0x10, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, + 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0f, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x12, + 0x30, 0x0a, 0x10, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x69, 0x6e, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, + 0x52, 0x0f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, + 0x67, 0x22, 0xad, 0x09, 0x0a, 0x0b, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x6a, 0x61, 0x76, 0x61, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6a, 0x61, 0x76, 0x61, 0x50, 0x61, 0x63, + 0x6b, 0x61, 0x67, 0x65, 0x12, 0x30, 0x0a, 0x14, 0x6a, 0x61, 0x76, 0x61, 0x5f, 0x6f, 0x75, 0x74, + 0x65, 0x72, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x12, 0x6a, 0x61, 0x76, 0x61, 0x4f, 0x75, 0x74, 0x65, 0x72, 0x43, 0x6c, 0x61, + 0x73, 0x73, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x13, 0x6a, 0x61, 0x76, 0x61, 0x5f, 0x6d, + 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x0a, 0x20, + 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x11, 0x6a, 0x61, 0x76, 0x61, + 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x44, 0x0a, + 0x1d, 0x6a, 0x61, 0x76, 0x61, 0x5f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x65, + 0x71, 0x75, 0x61, 0x6c, 0x73, 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x14, + 0x20, 0x01, 0x28, 0x08, 0x42, 0x02, 0x18, 0x01, 0x52, 0x19, 0x6a, 0x61, 0x76, 0x61, 0x47, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x45, 0x71, 0x75, 0x61, 0x6c, 0x73, 0x41, 0x6e, 0x64, 0x48, + 0x61, 0x73, 0x68, 0x12, 0x3a, 0x0a, 0x16, 0x6a, 0x61, 0x76, 0x61, 0x5f, 0x73, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x75, 0x74, 0x66, 0x38, 0x18, 0x1b, 0x20, + 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x13, 0x6a, 0x61, 0x76, 0x61, + 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x55, 0x74, 0x66, 0x38, 0x12, + 0x53, 0x0a, 0x0c, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x29, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x4d, 0x6f, 0x64, 0x65, + 0x3a, 0x05, 0x53, 0x50, 0x45, 0x45, 0x44, 0x52, 0x0b, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, + 0x65, 0x46, 0x6f, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x6f, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x61, + 0x67, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x6f, 0x50, 0x61, 0x63, 0x6b, + 0x61, 0x67, 0x65, 0x12, 0x35, 0x0a, 0x13, 0x63, 0x63, 0x5f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, + 0x63, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, + 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x11, 0x63, 0x63, 0x47, 0x65, 0x6e, 0x65, 0x72, + 0x69, 0x63, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x39, 0x0a, 0x15, 0x6a, 0x61, + 0x76, 0x61, 0x5f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, + 0x52, 0x13, 0x6a, 0x61, 0x76, 0x61, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x35, 0x0a, 0x13, 0x70, 0x79, 0x5f, 0x67, 0x65, 0x6e, 0x65, + 0x72, 0x69, 0x63, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x12, 0x20, 0x01, + 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x11, 0x70, 0x79, 0x47, 0x65, 0x6e, + 0x65, 0x72, 0x69, 0x63, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0a, + 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x17, 0x20, 0x01, 0x28, 0x08, + 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, + 0x74, 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x10, 0x63, 0x63, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x5f, 0x61, 0x72, 0x65, 0x6e, 0x61, 0x73, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x04, 0x74, + 0x72, 0x75, 0x65, 0x52, 0x0e, 0x63, 0x63, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x41, 0x72, 0x65, + 0x6e, 0x61, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x6f, 0x62, 0x6a, 0x63, 0x5f, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x24, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, + 0x6f, 0x62, 0x6a, 0x63, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, + 0x29, 0x0a, 0x10, 0x63, 0x73, 0x68, 0x61, 0x72, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x18, 0x25, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x73, 0x68, 0x61, 0x72, + 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x77, + 0x69, 0x66, 0x74, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x27, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x73, 0x77, 0x69, 0x66, 0x74, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x28, 0x0a, + 0x10, 0x70, 0x68, 0x70, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, + 0x78, 0x18, 0x28, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x70, 0x68, 0x70, 0x43, 0x6c, 0x61, 0x73, + 0x73, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x68, 0x70, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x29, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, + 0x70, 0x68, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x34, 0x0a, 0x16, + 0x70, 0x68, 0x70, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x2c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x70, 0x68, + 0x70, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x75, 0x62, 0x79, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x61, + 0x67, 0x65, 0x18, 0x2d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x75, 0x62, 0x79, 0x50, 0x61, + 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x37, 0x0a, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x73, 0x18, 0x32, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x53, 0x65, 0x74, 0x52, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x58, + 0x0a, 0x14, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x5f, + 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xe7, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, - 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x89, 0x02, 0x0a, 0x15, 0x4d, 0x65, 0x74, 0x68, - 0x6f, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x74, - 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x69, 0x6e, 0x70, 0x75, 0x74, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x74, - 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x75, 0x74, 0x70, 0x75, - 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x38, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, - 0x30, 0x0a, 0x10, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, - 0x69, 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, - 0x52, 0x0f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, - 0x67, 0x12, 0x30, 0x0a, 0x10, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x73, 0x74, 0x72, 0x65, - 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, - 0x73, 0x65, 0x52, 0x0f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, - 0x69, 0x6e, 0x67, 0x22, 0xad, 0x09, 0x0a, 0x0b, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x6a, 0x61, 0x76, 0x61, 0x5f, 0x70, 0x61, 0x63, 0x6b, - 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6a, 0x61, 0x76, 0x61, 0x50, - 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x30, 0x0a, 0x14, 0x6a, 0x61, 0x76, 0x61, 0x5f, 0x6f, - 0x75, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x6a, 0x61, 0x76, 0x61, 0x4f, 0x75, 0x74, 0x65, 0x72, 0x43, - 0x6c, 0x61, 0x73, 0x73, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x13, 0x6a, 0x61, 0x76, 0x61, - 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, - 0x0a, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x11, 0x6a, 0x61, - 0x76, 0x61, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, - 0x44, 0x0a, 0x1d, 0x6a, 0x61, 0x76, 0x61, 0x5f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, - 0x5f, 0x65, 0x71, 0x75, 0x61, 0x6c, 0x73, 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x68, 0x61, 0x73, 0x68, - 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x42, 0x02, 0x18, 0x01, 0x52, 0x19, 0x6a, 0x61, 0x76, 0x61, - 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x45, 0x71, 0x75, 0x61, 0x6c, 0x73, 0x41, 0x6e, - 0x64, 0x48, 0x61, 0x73, 0x68, 0x12, 0x3a, 0x0a, 0x16, 0x6a, 0x61, 0x76, 0x61, 0x5f, 0x73, 0x74, - 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x75, 0x74, 0x66, 0x38, 0x18, - 0x1b, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x13, 0x6a, 0x61, - 0x76, 0x61, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x55, 0x74, 0x66, - 0x38, 0x12, 0x53, 0x0a, 0x0c, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x5f, 0x66, 0x6f, - 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x29, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x4d, 0x6f, - 0x64, 0x65, 0x3a, 0x05, 0x53, 0x50, 0x45, 0x45, 0x44, 0x52, 0x0b, 0x6f, 0x70, 0x74, 0x69, 0x6d, - 0x69, 0x7a, 0x65, 0x46, 0x6f, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x6f, 0x5f, 0x70, 0x61, 0x63, - 0x6b, 0x61, 0x67, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x6f, 0x50, 0x61, - 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x35, 0x0a, 0x13, 0x63, 0x63, 0x5f, 0x67, 0x65, 0x6e, 0x65, - 0x72, 0x69, 0x63, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x10, 0x20, 0x01, - 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x11, 0x63, 0x63, 0x47, 0x65, 0x6e, - 0x65, 0x72, 0x69, 0x63, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x39, 0x0a, 0x15, - 0x6a, 0x61, 0x76, 0x61, 0x5f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x5f, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, - 0x73, 0x65, 0x52, 0x13, 0x6a, 0x61, 0x76, 0x61, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x35, 0x0a, 0x13, 0x70, 0x79, 0x5f, 0x67, 0x65, - 0x6e, 0x65, 0x72, 0x69, 0x63, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x12, - 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x11, 0x70, 0x79, 0x47, - 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x25, - 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x17, 0x20, 0x01, - 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, - 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x10, 0x63, 0x63, 0x5f, 0x65, 0x6e, 0x61, 0x62, - 0x6c, 0x65, 0x5f, 0x61, 0x72, 0x65, 0x6e, 0x61, 0x73, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x08, 0x3a, - 0x04, 0x74, 0x72, 0x75, 0x65, 0x52, 0x0e, 0x63, 0x63, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x41, - 0x72, 0x65, 0x6e, 0x61, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x6f, 0x62, 0x6a, 0x63, 0x5f, 0x63, 0x6c, - 0x61, 0x73, 0x73, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x24, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0f, 0x6f, 0x62, 0x6a, 0x63, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x50, 0x72, 0x65, 0x66, 0x69, - 0x78, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x73, 0x68, 0x61, 0x72, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x25, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x73, 0x68, - 0x61, 0x72, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x21, 0x0a, 0x0c, - 0x73, 0x77, 0x69, 0x66, 0x74, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x27, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0b, 0x73, 0x77, 0x69, 0x66, 0x74, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, - 0x28, 0x0a, 0x10, 0x70, 0x68, 0x70, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x70, 0x72, 0x65, - 0x66, 0x69, 0x78, 0x18, 0x28, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x70, 0x68, 0x70, 0x43, 0x6c, - 0x61, 0x73, 0x73, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x68, 0x70, - 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x29, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0c, 0x70, 0x68, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x34, - 0x0a, 0x16, 0x70, 0x68, 0x70, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x2c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, - 0x70, 0x68, 0x70, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4e, 0x61, 0x6d, 0x65, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x75, 0x62, 0x79, 0x5f, 0x70, 0x61, 0x63, - 0x6b, 0x61, 0x67, 0x65, 0x18, 0x2d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x75, 0x62, 0x79, - 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x37, 0x0a, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, - 0x72, 0x65, 0x73, 0x18, 0x32, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x65, 0x61, 0x74, - 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x52, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, - 0x12, 0x58, 0x0a, 0x14, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, - 0x64, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xe7, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, - 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x0a, 0x0c, 0x4f, 0x70, - 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x50, - 0x45, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x49, - 0x5a, 0x45, 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c, 0x4c, 0x49, 0x54, 0x45, 0x5f, 0x52, 0x55, 0x4e, - 0x54, 0x49, 0x4d, 0x45, 0x10, 0x03, 0x2a, 0x09, 0x08, 0xe8, 0x07, 0x10, 0x80, 0x80, 0x80, 0x80, - 0x02, 0x4a, 0x04, 0x08, 0x2a, 0x10, 0x2b, 0x4a, 0x04, 0x08, 0x26, 0x10, 0x27, 0x52, 0x14, 0x70, - 0x68, 0x70, 0x5f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x73, 0x22, 0xf4, 0x03, 0x0a, 0x0e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3c, 0x0a, 0x17, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x77, 0x69, 0x72, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, - 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x14, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x65, 0x74, 0x57, 0x69, 0x72, 0x65, 0x46, 0x6f, - 0x72, 0x6d, 0x61, 0x74, 0x12, 0x4c, 0x0a, 0x1f, 0x6e, 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x6e, 0x64, - 0x61, 0x72, 0x64, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x61, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, - 0x61, 0x6c, 0x73, 0x65, 0x52, 0x1c, 0x6e, 0x6f, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, - 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x6f, 0x72, 0x12, 0x25, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0a, 0x64, - 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x61, 0x70, - 0x5f, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6d, 0x61, - 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x56, 0x0a, 0x26, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, - 0x61, 0x74, 0x65, 0x64, 0x5f, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, - 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x73, - 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x42, 0x02, 0x18, 0x01, 0x52, 0x22, 0x64, 0x65, 0x70, 0x72, - 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x4a, 0x73, 0x6f, 0x6e, - 0x46, 0x69, 0x65, 0x6c, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x73, 0x12, 0x37, - 0x0a, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x52, 0x08, 0x66, - 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x58, 0x0a, 0x14, 0x75, 0x6e, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, - 0xe7, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x75, 0x6e, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x2a, 0x09, 0x08, 0xe8, 0x07, 0x10, 0x80, 0x80, 0x80, 0x80, 0x02, 0x4a, 0x04, 0x08, 0x04, - 0x10, 0x05, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x4a, 0x04, 0x08, 0x06, 0x10, 0x07, 0x4a, 0x04, - 0x08, 0x08, 0x10, 0x09, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x22, 0x9d, 0x0d, 0x0a, 0x0c, 0x46, - 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x05, 0x63, - 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, - 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x43, 0x54, 0x79, 0x70, 0x65, 0x3a, - 0x06, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x52, 0x05, 0x63, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, - 0x0a, 0x06, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, - 0x70, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x12, 0x47, 0x0a, 0x06, 0x6a, 0x73, 0x74, 0x79, 0x70, 0x65, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x4a, 0x53, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x09, 0x4a, 0x53, - 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x52, 0x06, 0x6a, 0x73, 0x74, 0x79, 0x70, 0x65, 0x12, - 0x19, 0x0a, 0x04, 0x6c, 0x61, 0x7a, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, - 0x61, 0x6c, 0x73, 0x65, 0x52, 0x04, 0x6c, 0x61, 0x7a, 0x79, 0x12, 0x2e, 0x0a, 0x0f, 0x75, 0x6e, - 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, 0x6c, 0x61, 0x7a, 0x79, 0x18, 0x0f, 0x20, - 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0e, 0x75, 0x6e, 0x76, 0x65, - 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x4c, 0x61, 0x7a, 0x79, 0x12, 0x25, 0x0a, 0x0a, 0x64, 0x65, - 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, - 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, - 0x64, 0x12, 0x19, 0x0a, 0x04, 0x77, 0x65, 0x61, 0x6b, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x3a, - 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x04, 0x77, 0x65, 0x61, 0x6b, 0x12, 0x28, 0x0a, 0x0c, - 0x64, 0x65, 0x62, 0x75, 0x67, 0x5f, 0x72, 0x65, 0x64, 0x61, 0x63, 0x74, 0x18, 0x10, 0x20, 0x01, - 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0b, 0x64, 0x65, 0x62, 0x75, 0x67, - 0x52, 0x65, 0x64, 0x61, 0x63, 0x74, 0x12, 0x4b, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, - 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x48, 0x0a, 0x07, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x18, 0x13, - 0x20, 0x03, 0x28, 0x0e, 0x32, 0x2e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x55, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, + 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x0a, 0x0c, 0x4f, 0x70, 0x74, 0x69, + 0x6d, 0x69, 0x7a, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x50, 0x45, 0x45, + 0x44, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x49, 0x5a, 0x45, + 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c, 0x4c, 0x49, 0x54, 0x45, 0x5f, 0x52, 0x55, 0x4e, 0x54, 0x49, + 0x4d, 0x45, 0x10, 0x03, 0x2a, 0x09, 0x08, 0xe8, 0x07, 0x10, 0x80, 0x80, 0x80, 0x80, 0x02, 0x4a, + 0x04, 0x08, 0x2a, 0x10, 0x2b, 0x4a, 0x04, 0x08, 0x26, 0x10, 0x27, 0x52, 0x14, 0x70, 0x68, 0x70, + 0x5f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x73, 0x22, 0xf4, 0x03, 0x0a, 0x0e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3c, 0x0a, 0x17, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, + 0x73, 0x65, 0x74, 0x5f, 0x77, 0x69, 0x72, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x14, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x65, 0x74, 0x57, 0x69, 0x72, 0x65, 0x46, 0x6f, 0x72, 0x6d, + 0x61, 0x74, 0x12, 0x4c, 0x0a, 0x1f, 0x6e, 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, + 0x64, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, + 0x73, 0x65, 0x52, 0x1c, 0x6e, 0x6f, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x44, 0x65, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, + 0x12, 0x25, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0a, 0x64, 0x65, 0x70, + 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x61, 0x70, 0x5f, 0x65, + 0x6e, 0x74, 0x72, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6d, 0x61, 0x70, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x56, 0x0a, 0x26, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, + 0x65, 0x64, 0x5f, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x5f, 0x66, + 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x73, 0x18, 0x0b, + 0x20, 0x01, 0x28, 0x08, 0x42, 0x02, 0x18, 0x01, 0x52, 0x22, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, + 0x61, 0x74, 0x65, 0x64, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x4a, 0x73, 0x6f, 0x6e, 0x46, 0x69, + 0x65, 0x6c, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x73, 0x12, 0x37, 0x0a, 0x08, + 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x52, 0x08, 0x66, 0x65, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x58, 0x0a, 0x14, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xe7, 0x07, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, + 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x75, 0x6e, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2a, + 0x09, 0x08, 0xe8, 0x07, 0x10, 0x80, 0x80, 0x80, 0x80, 0x02, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, + 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x4a, 0x04, 0x08, 0x06, 0x10, 0x07, 0x4a, 0x04, 0x08, 0x08, + 0x10, 0x09, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x22, 0x9d, 0x0d, 0x0a, 0x0c, 0x46, 0x69, 0x65, + 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x05, 0x63, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x43, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x06, 0x53, + 0x54, 0x52, 0x49, 0x4e, 0x47, 0x52, 0x05, 0x63, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, + 0x70, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x70, 0x61, + 0x63, 0x6b, 0x65, 0x64, 0x12, 0x47, 0x0a, 0x06, 0x6a, 0x73, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x54, 0x79, 0x70, 0x65, 0x52, 0x07, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x12, 0x57, 0x0a, - 0x10, 0x65, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, - 0x73, 0x18, 0x14, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x6f, 0x6e, 0x73, 0x2e, 0x4a, 0x53, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x09, 0x4a, 0x53, 0x5f, 0x4e, + 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x52, 0x06, 0x6a, 0x73, 0x74, 0x79, 0x70, 0x65, 0x12, 0x19, 0x0a, + 0x04, 0x6c, 0x61, 0x7a, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, + 0x73, 0x65, 0x52, 0x04, 0x6c, 0x61, 0x7a, 0x79, 0x12, 0x2e, 0x0a, 0x0f, 0x75, 0x6e, 0x76, 0x65, + 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, 0x6c, 0x61, 0x7a, 0x79, 0x18, 0x0f, 0x20, 0x01, 0x28, + 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0e, 0x75, 0x6e, 0x76, 0x65, 0x72, 0x69, + 0x66, 0x69, 0x65, 0x64, 0x4c, 0x61, 0x7a, 0x79, 0x12, 0x25, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x72, + 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, + 0x6c, 0x73, 0x65, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, + 0x19, 0x0a, 0x04, 0x77, 0x65, 0x61, 0x6b, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, + 0x61, 0x6c, 0x73, 0x65, 0x52, 0x04, 0x77, 0x65, 0x61, 0x6b, 0x12, 0x28, 0x0a, 0x0c, 0x64, 0x65, + 0x62, 0x75, 0x67, 0x5f, 0x72, 0x65, 0x64, 0x61, 0x63, 0x74, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, + 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0b, 0x64, 0x65, 0x62, 0x75, 0x67, 0x52, 0x65, + 0x64, 0x61, 0x63, 0x74, 0x12, 0x4b, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x45, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, - 0x66, 0x61, 0x75, 0x6c, 0x74, 0x52, 0x0f, 0x65, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, - 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x37, 0x0a, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, - 0x65, 0x73, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, - 0x72, 0x65, 0x53, 0x65, 0x74, 0x52, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, - 0x55, 0x0a, 0x0f, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x73, 0x75, 0x70, 0x70, 0x6f, - 0x72, 0x74, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, - 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x0e, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x58, 0x0a, 0x14, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xe7, - 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, - 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x75, 0x6e, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x1a, 0x5a, 0x0a, 0x0e, 0x45, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x66, 0x61, 0x75, - 0x6c, 0x74, 0x12, 0x32, 0x0a, 0x07, 0x65, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x65, - 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x96, 0x02, 0x0a, - 0x0e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x12, - 0x47, 0x0a, 0x12, 0x65, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x74, 0x72, 0x6f, - 0x64, 0x75, 0x63, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x64, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x11, 0x65, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, - 0x74, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x64, 0x12, 0x47, 0x0a, 0x12, 0x65, 0x64, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x11, - 0x65, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, - 0x64, 0x12, 0x2f, 0x0a, 0x13, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, - 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x61, 0x72, 0x6e, 0x69, - 0x6e, 0x67, 0x12, 0x41, 0x0a, 0x0f, 0x65, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, - 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x64, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x65, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, - 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x22, 0x2f, 0x0a, 0x05, 0x43, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, - 0x0a, 0x06, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x43, 0x4f, - 0x52, 0x44, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x5f, 0x50, - 0x49, 0x45, 0x43, 0x45, 0x10, 0x02, 0x22, 0x35, 0x0a, 0x06, 0x4a, 0x53, 0x54, 0x79, 0x70, 0x65, - 0x12, 0x0d, 0x0a, 0x09, 0x4a, 0x53, 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x00, 0x12, - 0x0d, 0x0a, 0x09, 0x4a, 0x53, 0x5f, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0d, - 0x0a, 0x09, 0x4a, 0x53, 0x5f, 0x4e, 0x55, 0x4d, 0x42, 0x45, 0x52, 0x10, 0x02, 0x22, 0x55, 0x0a, - 0x0f, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x15, 0x0a, 0x11, 0x52, 0x45, 0x54, 0x45, 0x4e, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, - 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x52, 0x45, 0x54, 0x45, 0x4e, - 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, 0x55, 0x4e, 0x54, 0x49, 0x4d, 0x45, 0x10, 0x01, 0x12, 0x14, - 0x0a, 0x10, 0x52, 0x45, 0x54, 0x45, 0x4e, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x4f, 0x55, 0x52, - 0x43, 0x45, 0x10, 0x02, 0x22, 0x8c, 0x02, 0x0a, 0x10, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x54, - 0x61, 0x72, 0x67, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x41, 0x52, - 0x47, 0x45, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, - 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x5f, 0x54, 0x59, 0x50, - 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x1f, 0x0a, 0x1b, 0x54, 0x41, 0x52, 0x47, - 0x45, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x58, 0x54, 0x45, 0x4e, 0x53, 0x49, 0x4f, - 0x4e, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x02, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x41, 0x52, - 0x47, 0x45, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, - 0x10, 0x03, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x5f, 0x54, 0x59, 0x50, - 0x45, 0x5f, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x10, 0x04, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x41, 0x52, - 0x47, 0x45, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4f, 0x4e, 0x45, 0x4f, 0x46, 0x10, 0x05, - 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, - 0x45, 0x4e, 0x55, 0x4d, 0x10, 0x06, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54, - 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x45, 0x4e, 0x54, 0x52, 0x59, - 0x10, 0x07, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x5f, 0x54, 0x59, 0x50, - 0x45, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x10, 0x08, 0x12, 0x16, 0x0a, 0x12, 0x54, - 0x41, 0x52, 0x47, 0x45, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, - 0x44, 0x10, 0x09, 0x2a, 0x09, 0x08, 0xe8, 0x07, 0x10, 0x80, 0x80, 0x80, 0x80, 0x02, 0x4a, 0x04, - 0x08, 0x04, 0x10, 0x05, 0x4a, 0x04, 0x08, 0x12, 0x10, 0x13, 0x22, 0xac, 0x01, 0x0a, 0x0c, 0x4f, - 0x6e, 0x65, 0x6f, 0x66, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x37, 0x0a, 0x08, 0x66, - 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x52, 0x08, 0x66, 0x65, 0x61, 0x74, - 0x75, 0x72, 0x65, 0x73, 0x12, 0x58, 0x0a, 0x14, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x74, + 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x48, 0x0a, 0x07, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x18, 0x13, 0x20, 0x03, + 0x28, 0x0e, 0x32, 0x2e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x54, 0x79, + 0x70, 0x65, 0x52, 0x07, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x12, 0x57, 0x0a, 0x10, 0x65, + 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x18, + 0x14, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x45, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x52, 0x0f, 0x65, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x73, 0x12, 0x37, 0x0a, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, + 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x53, 0x65, 0x74, 0x52, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x55, 0x0a, + 0x0f, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, + 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x75, 0x70, + 0x70, 0x6f, 0x72, 0x74, 0x52, 0x0e, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x75, 0x70, + 0x70, 0x6f, 0x72, 0x74, 0x12, 0x58, 0x0a, 0x14, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xe7, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x75, 0x6e, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2a, 0x09, - 0x08, 0xe8, 0x07, 0x10, 0x80, 0x80, 0x80, 0x80, 0x02, 0x22, 0xd1, 0x02, 0x0a, 0x0b, 0x45, 0x6e, - 0x75, 0x6d, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x6c, 0x6c, - 0x6f, 0x77, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, - 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x25, 0x0a, 0x0a, 0x64, 0x65, - 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, - 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, - 0x64, 0x12, 0x56, 0x0a, 0x26, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x5f, - 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x5f, 0x66, 0x69, 0x65, 0x6c, - 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x08, 0x42, 0x02, 0x18, 0x01, 0x52, 0x22, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, - 0x64, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x4a, 0x73, 0x6f, 0x6e, 0x46, 0x69, 0x65, 0x6c, 0x64, - 0x43, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x73, 0x12, 0x37, 0x0a, 0x08, 0x66, 0x65, 0x61, - 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, + 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x5a, + 0x0a, 0x0e, 0x45, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, + 0x12, 0x32, 0x0a, 0x07, 0x65, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x18, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x45, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x65, 0x64, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x96, 0x02, 0x0a, 0x0e, 0x46, + 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x47, 0x0a, + 0x12, 0x65, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x74, 0x72, 0x6f, 0x64, 0x75, + 0x63, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x64, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x11, 0x65, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x74, 0x72, + 0x6f, 0x64, 0x75, 0x63, 0x65, 0x64, 0x12, 0x47, 0x0a, 0x12, 0x65, 0x64, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x11, 0x65, 0x64, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, + 0x2f, 0x0a, 0x13, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x77, + 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x64, 0x65, + 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x57, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, + 0x12, 0x41, 0x0a, 0x0f, 0x65, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x64, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x65, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x64, 0x22, 0x2f, 0x0a, 0x05, 0x43, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, + 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x43, 0x4f, 0x52, 0x44, + 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x5f, 0x50, 0x49, 0x45, + 0x43, 0x45, 0x10, 0x02, 0x22, 0x35, 0x0a, 0x06, 0x4a, 0x53, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0d, + 0x0a, 0x09, 0x4a, 0x53, 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x00, 0x12, 0x0d, 0x0a, + 0x09, 0x4a, 0x53, 0x5f, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, + 0x4a, 0x53, 0x5f, 0x4e, 0x55, 0x4d, 0x42, 0x45, 0x52, 0x10, 0x02, 0x22, 0x55, 0x0a, 0x0f, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x15, + 0x0a, 0x11, 0x52, 0x45, 0x54, 0x45, 0x4e, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, + 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x52, 0x45, 0x54, 0x45, 0x4e, 0x54, 0x49, + 0x4f, 0x4e, 0x5f, 0x52, 0x55, 0x4e, 0x54, 0x49, 0x4d, 0x45, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, + 0x52, 0x45, 0x54, 0x45, 0x4e, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, + 0x10, 0x02, 0x22, 0x8c, 0x02, 0x0a, 0x10, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x72, + 0x67, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x41, 0x52, 0x47, 0x45, + 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, + 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, + 0x46, 0x49, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x1f, 0x0a, 0x1b, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54, + 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x58, 0x54, 0x45, 0x4e, 0x53, 0x49, 0x4f, 0x4e, 0x5f, + 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x02, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x41, 0x52, 0x47, 0x45, + 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x10, 0x03, + 0x12, 0x15, 0x0a, 0x11, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, + 0x46, 0x49, 0x45, 0x4c, 0x44, 0x10, 0x04, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x41, 0x52, 0x47, 0x45, + 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4f, 0x4e, 0x45, 0x4f, 0x46, 0x10, 0x05, 0x12, 0x14, + 0x0a, 0x10, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x4e, + 0x55, 0x4d, 0x10, 0x06, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x5f, 0x54, + 0x59, 0x50, 0x45, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x45, 0x4e, 0x54, 0x52, 0x59, 0x10, 0x07, + 0x12, 0x17, 0x0a, 0x13, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, + 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x10, 0x08, 0x12, 0x16, 0x0a, 0x12, 0x54, 0x41, 0x52, + 0x47, 0x45, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x10, + 0x09, 0x2a, 0x09, 0x08, 0xe8, 0x07, 0x10, 0x80, 0x80, 0x80, 0x80, 0x02, 0x4a, 0x04, 0x08, 0x04, + 0x10, 0x05, 0x4a, 0x04, 0x08, 0x12, 0x10, 0x13, 0x22, 0xac, 0x01, 0x0a, 0x0c, 0x4f, 0x6e, 0x65, + 0x6f, 0x66, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x37, 0x0a, 0x08, 0x66, 0x65, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x52, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x58, 0x0a, 0x14, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, @@ -4893,284 +4841,306 @@ var file_google_protobuf_descriptor_proto_rawDesc = []byte{ 0x62, 0x75, 0x66, 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2a, 0x09, 0x08, 0xe8, - 0x07, 0x10, 0x80, 0x80, 0x80, 0x80, 0x02, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x22, 0xd8, 0x02, - 0x0a, 0x10, 0x45, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x12, 0x25, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0a, 0x64, - 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x37, 0x0a, 0x08, 0x66, 0x65, 0x61, - 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, + 0x07, 0x10, 0x80, 0x80, 0x80, 0x80, 0x02, 0x22, 0xd1, 0x02, 0x0a, 0x0b, 0x45, 0x6e, 0x75, 0x6d, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x6c, 0x6c, 0x6f, 0x77, + 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x61, 0x6c, + 0x6c, 0x6f, 0x77, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x25, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x72, + 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, + 0x6c, 0x73, 0x65, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, + 0x56, 0x0a, 0x26, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x6c, 0x65, + 0x67, 0x61, 0x63, 0x79, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, + 0x63, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x42, + 0x02, 0x18, 0x01, 0x52, 0x22, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x4c, + 0x65, 0x67, 0x61, 0x63, 0x79, 0x4a, 0x73, 0x6f, 0x6e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x43, 0x6f, + 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x73, 0x12, 0x37, 0x0a, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x65, 0x61, 0x74, + 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x52, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, + 0x12, 0x58, 0x0a, 0x14, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, + 0x64, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xe7, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, + 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2a, 0x09, 0x08, 0xe8, 0x07, 0x10, + 0x80, 0x80, 0x80, 0x80, 0x02, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x22, 0xd8, 0x02, 0x0a, 0x10, + 0x45, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x12, 0x25, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0a, 0x64, 0x65, 0x70, + 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x37, 0x0a, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x65, 0x61, 0x74, + 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x52, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, + 0x12, 0x28, 0x0a, 0x0c, 0x64, 0x65, 0x62, 0x75, 0x67, 0x5f, 0x72, 0x65, 0x64, 0x61, 0x63, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0b, 0x64, + 0x65, 0x62, 0x75, 0x67, 0x52, 0x65, 0x64, 0x61, 0x63, 0x74, 0x12, 0x55, 0x0a, 0x0f, 0x66, 0x65, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, + 0x74, 0x52, 0x0e, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, + 0x74, 0x12, 0x58, 0x0a, 0x14, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, + 0x65, 0x64, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xe7, 0x07, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, + 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2a, 0x09, 0x08, 0xe8, 0x07, + 0x10, 0x80, 0x80, 0x80, 0x80, 0x02, 0x22, 0xd5, 0x01, 0x0a, 0x0e, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x37, 0x0a, 0x08, 0x66, 0x65, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x22, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x52, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, - 0x65, 0x73, 0x12, 0x28, 0x0a, 0x0c, 0x64, 0x65, 0x62, 0x75, 0x67, 0x5f, 0x72, 0x65, 0x64, 0x61, - 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, - 0x0b, 0x64, 0x65, 0x62, 0x75, 0x67, 0x52, 0x65, 0x64, 0x61, 0x63, 0x74, 0x12, 0x55, 0x0a, 0x0f, - 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x75, 0x70, 0x70, - 0x6f, 0x72, 0x74, 0x52, 0x0e, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x75, 0x70, 0x70, - 0x6f, 0x72, 0x74, 0x12, 0x58, 0x0a, 0x14, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, + 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, + 0x18, 0x21, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0a, 0x64, + 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x58, 0x0a, 0x14, 0x75, 0x6e, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0xe7, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, + 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x2a, 0x09, 0x08, 0xe8, 0x07, 0x10, 0x80, 0x80, 0x80, 0x80, 0x02, 0x22, 0x99, + 0x03, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x12, 0x25, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x21, + 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0a, 0x64, 0x65, 0x70, + 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x71, 0x0a, 0x11, 0x69, 0x64, 0x65, 0x6d, 0x70, + 0x6f, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x22, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x2f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x2e, 0x49, 0x64, 0x65, 0x6d, 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x4c, 0x65, + 0x76, 0x65, 0x6c, 0x3a, 0x13, 0x49, 0x44, 0x45, 0x4d, 0x50, 0x4f, 0x54, 0x45, 0x4e, 0x43, 0x59, + 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x52, 0x10, 0x69, 0x64, 0x65, 0x6d, 0x70, 0x6f, + 0x74, 0x65, 0x6e, 0x63, 0x79, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x37, 0x0a, 0x08, 0x66, 0x65, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x23, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, + 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x52, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x73, 0x12, 0x58, 0x0a, 0x14, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xe7, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2a, 0x09, 0x08, - 0xe8, 0x07, 0x10, 0x80, 0x80, 0x80, 0x80, 0x02, 0x22, 0xd5, 0x01, 0x0a, 0x0e, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x37, 0x0a, 0x08, 0x66, - 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x22, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, + 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x50, 0x0a, + 0x10, 0x49, 0x64, 0x65, 0x6d, 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x4c, 0x65, 0x76, 0x65, + 0x6c, 0x12, 0x17, 0x0a, 0x13, 0x49, 0x44, 0x45, 0x4d, 0x50, 0x4f, 0x54, 0x45, 0x4e, 0x43, 0x59, + 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x4e, 0x4f, + 0x5f, 0x53, 0x49, 0x44, 0x45, 0x5f, 0x45, 0x46, 0x46, 0x45, 0x43, 0x54, 0x53, 0x10, 0x01, 0x12, + 0x0e, 0x0a, 0x0a, 0x49, 0x44, 0x45, 0x4d, 0x50, 0x4f, 0x54, 0x45, 0x4e, 0x54, 0x10, 0x02, 0x2a, + 0x09, 0x08, 0xe8, 0x07, 0x10, 0x80, 0x80, 0x80, 0x80, 0x02, 0x22, 0x9a, 0x03, 0x0a, 0x13, 0x55, + 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x41, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x2d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x61, 0x72, 0x74, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, + 0x69, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x12, 0x2c, 0x0a, 0x12, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x69, 0x6e, 0x74, + 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x10, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x49, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2c, + 0x0a, 0x12, 0x6e, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x5f, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x6e, 0x65, 0x67, 0x61, + 0x74, 0x69, 0x76, 0x65, 0x49, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x21, 0x0a, 0x0c, + 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x01, 0x52, 0x0b, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, + 0x21, 0x0a, 0x0c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x5f, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x61, 0x67, 0x67, + 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x4a, 0x0a, 0x08, 0x4e, + 0x61, 0x6d, 0x65, 0x50, 0x61, 0x72, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x5f, + 0x70, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x02, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x61, 0x6d, 0x65, + 0x50, 0x61, 0x72, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x73, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x02, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, 0x45, 0x78, + 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xa7, 0x0a, 0x0a, 0x0a, 0x46, 0x65, 0x61, 0x74, + 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x12, 0x91, 0x01, 0x0a, 0x0e, 0x66, 0x69, 0x65, 0x6c, 0x64, + 0x5f, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x29, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x2e, 0x46, 0x69, 0x65, + 0x6c, 0x64, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x3f, 0x88, 0x01, 0x01, 0x98, + 0x01, 0x04, 0x98, 0x01, 0x01, 0xa2, 0x01, 0x0d, 0x12, 0x08, 0x45, 0x58, 0x50, 0x4c, 0x49, 0x43, + 0x49, 0x54, 0x18, 0x84, 0x07, 0xa2, 0x01, 0x0d, 0x12, 0x08, 0x49, 0x4d, 0x50, 0x4c, 0x49, 0x43, + 0x49, 0x54, 0x18, 0xe7, 0x07, 0xa2, 0x01, 0x0d, 0x12, 0x08, 0x45, 0x58, 0x50, 0x4c, 0x49, 0x43, + 0x49, 0x54, 0x18, 0xe8, 0x07, 0xb2, 0x01, 0x03, 0x08, 0xe8, 0x07, 0x52, 0x0d, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x6c, 0x0a, 0x09, 0x65, 0x6e, + 0x75, 0x6d, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x52, 0x08, 0x66, 0x65, 0x61, 0x74, - 0x75, 0x72, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, - 0x65, 0x64, 0x18, 0x21, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, - 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x58, 0x0a, 0x14, 0x75, - 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0xe7, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x6e, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x13, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2a, 0x09, 0x08, 0xe8, 0x07, 0x10, 0x80, 0x80, 0x80, 0x80, 0x02, - 0x22, 0x99, 0x03, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x12, 0x25, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, - 0x18, 0x21, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0a, 0x64, - 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x71, 0x0a, 0x11, 0x69, 0x64, 0x65, - 0x6d, 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x22, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x49, 0x64, 0x65, 0x6d, 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x63, 0x79, - 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x3a, 0x13, 0x49, 0x44, 0x45, 0x4d, 0x50, 0x4f, 0x54, 0x45, 0x4e, - 0x43, 0x59, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x52, 0x10, 0x69, 0x64, 0x65, 0x6d, - 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x37, 0x0a, 0x08, - 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x23, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x52, 0x08, 0x66, 0x65, 0x61, - 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x58, 0x0a, 0x14, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xe7, 0x07, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, - 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x75, 0x6e, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, - 0x50, 0x0a, 0x10, 0x49, 0x64, 0x65, 0x6d, 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x4c, 0x65, - 0x76, 0x65, 0x6c, 0x12, 0x17, 0x0a, 0x13, 0x49, 0x44, 0x45, 0x4d, 0x50, 0x4f, 0x54, 0x45, 0x4e, - 0x43, 0x59, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, - 0x4e, 0x4f, 0x5f, 0x53, 0x49, 0x44, 0x45, 0x5f, 0x45, 0x46, 0x46, 0x45, 0x43, 0x54, 0x53, 0x10, - 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x49, 0x44, 0x45, 0x4d, 0x50, 0x4f, 0x54, 0x45, 0x4e, 0x54, 0x10, - 0x02, 0x2a, 0x09, 0x08, 0xe8, 0x07, 0x10, 0x80, 0x80, 0x80, 0x80, 0x02, 0x22, 0x9a, 0x03, 0x0a, - 0x13, 0x55, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x41, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, - 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x61, 0x72, - 0x74, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x64, 0x65, 0x6e, 0x74, - 0x69, 0x66, 0x69, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x69, - 0x6e, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x10, - 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x49, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x12, 0x2c, 0x0a, 0x12, 0x6e, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x69, 0x6e, 0x74, - 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x6e, 0x65, - 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x49, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x21, - 0x0a, 0x0c, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x01, 0x52, 0x0b, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, - 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x61, - 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x4a, 0x0a, - 0x08, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x61, 0x72, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x61, 0x6d, - 0x65, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x02, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x61, - 0x6d, 0x65, 0x50, 0x61, 0x72, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x73, 0x5f, 0x65, 0x78, 0x74, - 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x02, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, - 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xa7, 0x0a, 0x0a, 0x0a, 0x46, 0x65, - 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x12, 0x91, 0x01, 0x0a, 0x0e, 0x66, 0x69, 0x65, - 0x6c, 0x64, 0x5f, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x29, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x2e, 0x46, - 0x69, 0x65, 0x6c, 0x64, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x3f, 0x88, 0x01, - 0x01, 0x98, 0x01, 0x04, 0x98, 0x01, 0x01, 0xa2, 0x01, 0x0d, 0x12, 0x08, 0x45, 0x58, 0x50, 0x4c, - 0x49, 0x43, 0x49, 0x54, 0x18, 0xe6, 0x07, 0xa2, 0x01, 0x0d, 0x12, 0x08, 0x49, 0x4d, 0x50, 0x4c, - 0x49, 0x43, 0x49, 0x54, 0x18, 0xe7, 0x07, 0xa2, 0x01, 0x0d, 0x12, 0x08, 0x45, 0x58, 0x50, 0x4c, - 0x49, 0x43, 0x49, 0x54, 0x18, 0xe8, 0x07, 0xb2, 0x01, 0x03, 0x08, 0xe8, 0x07, 0x52, 0x0d, 0x66, - 0x69, 0x65, 0x6c, 0x64, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x6c, 0x0a, 0x09, - 0x65, 0x6e, 0x75, 0x6d, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x2e, 0x45, 0x6e, 0x75, - 0x6d, 0x54, 0x79, 0x70, 0x65, 0x42, 0x29, 0x88, 0x01, 0x01, 0x98, 0x01, 0x06, 0x98, 0x01, 0x01, - 0xa2, 0x01, 0x0b, 0x12, 0x06, 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x44, 0x18, 0xe6, 0x07, 0xa2, 0x01, - 0x09, 0x12, 0x04, 0x4f, 0x50, 0x45, 0x4e, 0x18, 0xe7, 0x07, 0xb2, 0x01, 0x03, 0x08, 0xe8, 0x07, - 0x52, 0x08, 0x65, 0x6e, 0x75, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x12, 0x98, 0x01, 0x0a, 0x17, 0x72, - 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x65, 0x6e, - 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x31, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, - 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x2e, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, - 0x65, 0x64, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x42, - 0x2d, 0x88, 0x01, 0x01, 0x98, 0x01, 0x04, 0x98, 0x01, 0x01, 0xa2, 0x01, 0x0d, 0x12, 0x08, 0x45, - 0x58, 0x50, 0x41, 0x4e, 0x44, 0x45, 0x44, 0x18, 0xe6, 0x07, 0xa2, 0x01, 0x0b, 0x12, 0x06, 0x50, - 0x41, 0x43, 0x4b, 0x45, 0x44, 0x18, 0xe7, 0x07, 0xb2, 0x01, 0x03, 0x08, 0xe8, 0x07, 0x52, 0x15, - 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x6e, 0x63, - 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x7e, 0x0a, 0x0f, 0x75, 0x74, 0x66, 0x38, 0x5f, 0x76, 0x61, - 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x2e, 0x55, 0x74, 0x66, 0x38, - 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x29, 0x88, 0x01, 0x01, 0x98, - 0x01, 0x04, 0x98, 0x01, 0x01, 0xa2, 0x01, 0x09, 0x12, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x18, 0xe6, - 0x07, 0xa2, 0x01, 0x0b, 0x12, 0x06, 0x56, 0x45, 0x52, 0x49, 0x46, 0x59, 0x18, 0xe7, 0x07, 0xb2, - 0x01, 0x03, 0x08, 0xe8, 0x07, 0x52, 0x0e, 0x75, 0x74, 0x66, 0x38, 0x56, 0x61, 0x6c, 0x69, 0x64, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x7e, 0x0a, 0x10, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x5f, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x2b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x2e, 0x4d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x42, 0x26, 0x88, 0x01, - 0x01, 0x98, 0x01, 0x04, 0x98, 0x01, 0x01, 0xa2, 0x01, 0x14, 0x12, 0x0f, 0x4c, 0x45, 0x4e, 0x47, - 0x54, 0x48, 0x5f, 0x50, 0x52, 0x45, 0x46, 0x49, 0x58, 0x45, 0x44, 0x18, 0xe6, 0x07, 0xb2, 0x01, - 0x03, 0x08, 0xe8, 0x07, 0x52, 0x0f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x45, 0x6e, 0x63, - 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x82, 0x01, 0x0a, 0x0b, 0x6a, 0x73, 0x6f, 0x6e, 0x5f, 0x66, - 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x65, - 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x2e, 0x4a, 0x73, 0x6f, 0x6e, 0x46, 0x6f, 0x72, - 0x6d, 0x61, 0x74, 0x42, 0x39, 0x88, 0x01, 0x01, 0x98, 0x01, 0x03, 0x98, 0x01, 0x06, 0x98, 0x01, - 0x01, 0xa2, 0x01, 0x17, 0x12, 0x12, 0x4c, 0x45, 0x47, 0x41, 0x43, 0x59, 0x5f, 0x42, 0x45, 0x53, - 0x54, 0x5f, 0x45, 0x46, 0x46, 0x4f, 0x52, 0x54, 0x18, 0xe6, 0x07, 0xa2, 0x01, 0x0a, 0x12, 0x05, - 0x41, 0x4c, 0x4c, 0x4f, 0x57, 0x18, 0xe7, 0x07, 0xb2, 0x01, 0x03, 0x08, 0xe8, 0x07, 0x52, 0x0a, - 0x6a, 0x73, 0x6f, 0x6e, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0x5c, 0x0a, 0x0d, 0x46, 0x69, - 0x65, 0x6c, 0x64, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x16, 0x46, - 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x50, 0x52, 0x45, 0x53, 0x45, 0x4e, 0x43, 0x45, 0x5f, 0x55, 0x4e, - 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x45, 0x58, 0x50, 0x4c, 0x49, - 0x43, 0x49, 0x54, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x49, 0x4d, 0x50, 0x4c, 0x49, 0x43, 0x49, - 0x54, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x45, 0x47, 0x41, 0x43, 0x59, 0x5f, 0x52, 0x45, - 0x51, 0x55, 0x49, 0x52, 0x45, 0x44, 0x10, 0x03, 0x22, 0x37, 0x0a, 0x08, 0x45, 0x6e, 0x75, 0x6d, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x15, 0x0a, 0x11, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x54, 0x59, 0x50, - 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x4f, - 0x50, 0x45, 0x4e, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x44, 0x10, - 0x02, 0x22, 0x56, 0x0a, 0x15, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x46, 0x69, 0x65, - 0x6c, 0x64, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x45, - 0x50, 0x45, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x45, 0x4e, 0x43, - 0x4f, 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, - 0x0a, 0x0a, 0x06, 0x50, 0x41, 0x43, 0x4b, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x45, - 0x58, 0x50, 0x41, 0x4e, 0x44, 0x45, 0x44, 0x10, 0x02, 0x22, 0x49, 0x0a, 0x0e, 0x55, 0x74, 0x66, - 0x38, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x17, 0x55, - 0x54, 0x46, 0x38, 0x5f, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, - 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x56, 0x45, 0x52, 0x49, - 0x46, 0x59, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x03, 0x22, 0x04, - 0x08, 0x01, 0x10, 0x01, 0x22, 0x53, 0x0a, 0x0f, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x45, - 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x1c, 0x0a, 0x18, 0x4d, 0x45, 0x53, 0x53, 0x41, - 0x47, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x4f, 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, - 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x45, 0x4e, 0x47, 0x54, 0x48, 0x5f, - 0x50, 0x52, 0x45, 0x46, 0x49, 0x58, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x44, 0x45, - 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x45, 0x44, 0x10, 0x02, 0x22, 0x48, 0x0a, 0x0a, 0x4a, 0x73, 0x6f, - 0x6e, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x17, 0x0a, 0x13, 0x4a, 0x53, 0x4f, 0x4e, 0x5f, - 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, - 0x12, 0x09, 0x0a, 0x05, 0x41, 0x4c, 0x4c, 0x4f, 0x57, 0x10, 0x01, 0x12, 0x16, 0x0a, 0x12, 0x4c, - 0x45, 0x47, 0x41, 0x43, 0x59, 0x5f, 0x42, 0x45, 0x53, 0x54, 0x5f, 0x45, 0x46, 0x46, 0x4f, 0x52, - 0x54, 0x10, 0x02, 0x2a, 0x06, 0x08, 0xe8, 0x07, 0x10, 0x8b, 0x4e, 0x2a, 0x06, 0x08, 0x8b, 0x4e, - 0x10, 0x90, 0x4e, 0x2a, 0x06, 0x08, 0x90, 0x4e, 0x10, 0x91, 0x4e, 0x4a, 0x06, 0x08, 0xe7, 0x07, - 0x10, 0xe8, 0x07, 0x22, 0xef, 0x03, 0x0a, 0x12, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, - 0x65, 0x74, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x58, 0x0a, 0x08, 0x64, 0x65, - 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3c, 0x2e, 0x67, + 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x54, + 0x79, 0x70, 0x65, 0x42, 0x29, 0x88, 0x01, 0x01, 0x98, 0x01, 0x06, 0x98, 0x01, 0x01, 0xa2, 0x01, + 0x0b, 0x12, 0x06, 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x44, 0x18, 0x84, 0x07, 0xa2, 0x01, 0x09, 0x12, + 0x04, 0x4f, 0x50, 0x45, 0x4e, 0x18, 0xe7, 0x07, 0xb2, 0x01, 0x03, 0x08, 0xe8, 0x07, 0x52, 0x08, + 0x65, 0x6e, 0x75, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x12, 0x98, 0x01, 0x0a, 0x17, 0x72, 0x65, 0x70, + 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x65, 0x6e, 0x63, 0x6f, + 0x64, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x31, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x65, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x2e, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x46, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x42, 0x2d, 0x88, + 0x01, 0x01, 0x98, 0x01, 0x04, 0x98, 0x01, 0x01, 0xa2, 0x01, 0x0d, 0x12, 0x08, 0x45, 0x58, 0x50, + 0x41, 0x4e, 0x44, 0x45, 0x44, 0x18, 0x84, 0x07, 0xa2, 0x01, 0x0b, 0x12, 0x06, 0x50, 0x41, 0x43, + 0x4b, 0x45, 0x44, 0x18, 0xe7, 0x07, 0xb2, 0x01, 0x03, 0x08, 0xe8, 0x07, 0x52, 0x15, 0x72, 0x65, + 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x6e, 0x63, 0x6f, 0x64, + 0x69, 0x6e, 0x67, 0x12, 0x7e, 0x0a, 0x0f, 0x75, 0x74, 0x66, 0x38, 0x5f, 0x76, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, - 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, - 0x73, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x45, 0x64, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x52, 0x08, 0x64, 0x65, 0x66, 0x61, - 0x75, 0x6c, 0x74, 0x73, 0x12, 0x41, 0x0a, 0x0f, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x5f, - 0x65, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, + 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x2e, 0x55, 0x74, 0x66, 0x38, 0x56, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x29, 0x88, 0x01, 0x01, 0x98, 0x01, 0x04, + 0x98, 0x01, 0x01, 0xa2, 0x01, 0x09, 0x12, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x18, 0x84, 0x07, 0xa2, + 0x01, 0x0b, 0x12, 0x06, 0x56, 0x45, 0x52, 0x49, 0x46, 0x59, 0x18, 0xe7, 0x07, 0xb2, 0x01, 0x03, + 0x08, 0xe8, 0x07, 0x52, 0x0e, 0x75, 0x74, 0x66, 0x38, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x7e, 0x0a, 0x10, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x65, + 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x45, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, - 0x45, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x41, 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x69, 0x6d, - 0x75, 0x6d, 0x5f, 0x65, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x18, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x45, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x6d, 0x61, 0x78, 0x69, - 0x6d, 0x75, 0x6d, 0x45, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0xf8, 0x01, 0x0a, 0x18, 0x46, - 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x45, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x12, 0x32, 0x0a, 0x07, 0x65, 0x64, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x64, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x07, 0x65, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x4e, 0x0a, 0x14, 0x6f, - 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x66, 0x65, 0x61, 0x74, 0x75, - 0x72, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x42, 0x26, 0x88, 0x01, 0x01, 0x98, + 0x01, 0x04, 0x98, 0x01, 0x01, 0xa2, 0x01, 0x14, 0x12, 0x0f, 0x4c, 0x45, 0x4e, 0x47, 0x54, 0x48, + 0x5f, 0x50, 0x52, 0x45, 0x46, 0x49, 0x58, 0x45, 0x44, 0x18, 0x84, 0x07, 0xb2, 0x01, 0x03, 0x08, + 0xe8, 0x07, 0x52, 0x0f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x45, 0x6e, 0x63, 0x6f, 0x64, + 0x69, 0x6e, 0x67, 0x12, 0x82, 0x01, 0x0a, 0x0b, 0x6a, 0x73, 0x6f, 0x6e, 0x5f, 0x66, 0x6f, 0x72, + 0x6d, 0x61, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x65, 0x61, 0x74, - 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x52, 0x13, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x61, - 0x62, 0x6c, 0x65, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x42, 0x0a, 0x0e, 0x66, - 0x69, 0x78, 0x65, 0x64, 0x5f, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, - 0x52, 0x0d, 0x66, 0x69, 0x78, 0x65, 0x64, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x4a, - 0x04, 0x08, 0x01, 0x10, 0x02, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x08, 0x66, 0x65, 0x61, - 0x74, 0x75, 0x72, 0x65, 0x73, 0x22, 0xa7, 0x02, 0x0a, 0x0e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x43, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x44, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x4c, 0x6f, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0xce, - 0x01, 0x0a, 0x08, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x04, 0x70, - 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x03, 0x28, 0x05, 0x42, 0x02, 0x10, 0x01, 0x52, 0x04, 0x70, - 0x61, 0x74, 0x68, 0x12, 0x16, 0x0a, 0x04, 0x73, 0x70, 0x61, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x05, 0x42, 0x02, 0x10, 0x01, 0x52, 0x04, 0x73, 0x70, 0x61, 0x6e, 0x12, 0x29, 0x0a, 0x10, 0x6c, - 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x6c, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, - 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x74, 0x72, 0x61, 0x69, 0x6c, 0x69, - 0x6e, 0x67, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x10, 0x74, 0x72, 0x61, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x65, - 0x6e, 0x74, 0x73, 0x12, 0x3a, 0x0a, 0x19, 0x6c, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x64, - 0x65, 0x74, 0x61, 0x63, 0x68, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, - 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x17, 0x6c, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x44, - 0x65, 0x74, 0x61, 0x63, 0x68, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, - 0xd0, 0x02, 0x0a, 0x11, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x64, - 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x4d, 0x0a, 0x0a, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x47, 0x65, 0x6e, 0x65, - 0x72, 0x61, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x41, 0x6e, - 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0xeb, 0x01, 0x0a, 0x0a, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x05, 0x42, 0x02, 0x10, 0x01, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x1f, 0x0a, 0x0b, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0a, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, - 0x62, 0x65, 0x67, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x62, 0x65, 0x67, - 0x69, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x03, 0x65, 0x6e, 0x64, 0x12, 0x52, 0x0a, 0x08, 0x73, 0x65, 0x6d, 0x61, 0x6e, 0x74, 0x69, 0x63, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x36, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, - 0x65, 0x64, 0x43, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x6d, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x52, 0x08, - 0x73, 0x65, 0x6d, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x22, 0x28, 0x0a, 0x08, 0x53, 0x65, 0x6d, 0x61, - 0x6e, 0x74, 0x69, 0x63, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x07, - 0x0a, 0x03, 0x53, 0x45, 0x54, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x4c, 0x49, 0x41, 0x53, - 0x10, 0x02, 0x2a, 0xa7, 0x02, 0x0a, 0x07, 0x45, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x13, - 0x0a, 0x0f, 0x45, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, - 0x4e, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0e, 0x45, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4c, - 0x45, 0x47, 0x41, 0x43, 0x59, 0x10, 0x84, 0x07, 0x12, 0x13, 0x0a, 0x0e, 0x45, 0x44, 0x49, 0x54, - 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x32, 0x10, 0xe6, 0x07, 0x12, 0x13, 0x0a, - 0x0e, 0x45, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x33, 0x10, - 0xe7, 0x07, 0x12, 0x11, 0x0a, 0x0c, 0x45, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x32, 0x30, - 0x32, 0x33, 0x10, 0xe8, 0x07, 0x12, 0x11, 0x0a, 0x0c, 0x45, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, - 0x5f, 0x32, 0x30, 0x32, 0x34, 0x10, 0xe9, 0x07, 0x12, 0x17, 0x0a, 0x13, 0x45, 0x44, 0x49, 0x54, - 0x49, 0x4f, 0x4e, 0x5f, 0x31, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x4f, 0x4e, 0x4c, 0x59, 0x10, - 0x01, 0x12, 0x17, 0x0a, 0x13, 0x45, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x32, 0x5f, 0x54, - 0x45, 0x53, 0x54, 0x5f, 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x02, 0x12, 0x1d, 0x0a, 0x17, 0x45, 0x44, - 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x39, 0x39, 0x39, 0x39, 0x37, 0x5f, 0x54, 0x45, 0x53, 0x54, - 0x5f, 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x9d, 0x8d, 0x06, 0x12, 0x1d, 0x0a, 0x17, 0x45, 0x44, 0x49, - 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x39, 0x39, 0x39, 0x39, 0x38, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x5f, - 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x9e, 0x8d, 0x06, 0x12, 0x1d, 0x0a, 0x17, 0x45, 0x44, 0x49, 0x54, - 0x49, 0x4f, 0x4e, 0x5f, 0x39, 0x39, 0x39, 0x39, 0x39, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x4f, - 0x4e, 0x4c, 0x59, 0x10, 0x9f, 0x8d, 0x06, 0x12, 0x13, 0x0a, 0x0b, 0x45, 0x44, 0x49, 0x54, 0x49, - 0x4f, 0x4e, 0x5f, 0x4d, 0x41, 0x58, 0x10, 0xff, 0xff, 0xff, 0xff, 0x07, 0x42, 0x7e, 0x0a, 0x13, - 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x42, 0x10, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x48, 0x01, 0x5a, 0x2d, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x6f, 0x72, 0x70, 0x62, 0xf8, 0x01, 0x01, 0xa2, 0x02, 0x03, 0x47, 0x50, 0x42, 0xaa, - 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x52, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, -} + 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x2e, 0x4a, 0x73, 0x6f, 0x6e, 0x46, 0x6f, 0x72, 0x6d, 0x61, + 0x74, 0x42, 0x39, 0x88, 0x01, 0x01, 0x98, 0x01, 0x03, 0x98, 0x01, 0x06, 0x98, 0x01, 0x01, 0xa2, + 0x01, 0x17, 0x12, 0x12, 0x4c, 0x45, 0x47, 0x41, 0x43, 0x59, 0x5f, 0x42, 0x45, 0x53, 0x54, 0x5f, + 0x45, 0x46, 0x46, 0x4f, 0x52, 0x54, 0x18, 0x84, 0x07, 0xa2, 0x01, 0x0a, 0x12, 0x05, 0x41, 0x4c, + 0x4c, 0x4f, 0x57, 0x18, 0xe7, 0x07, 0xb2, 0x01, 0x03, 0x08, 0xe8, 0x07, 0x52, 0x0a, 0x6a, 0x73, + 0x6f, 0x6e, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0x5c, 0x0a, 0x0d, 0x46, 0x69, 0x65, 0x6c, + 0x64, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x16, 0x46, 0x49, 0x45, + 0x4c, 0x44, 0x5f, 0x50, 0x52, 0x45, 0x53, 0x45, 0x4e, 0x43, 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, + 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x45, 0x58, 0x50, 0x4c, 0x49, 0x43, 0x49, + 0x54, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x49, 0x4d, 0x50, 0x4c, 0x49, 0x43, 0x49, 0x54, 0x10, + 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x45, 0x47, 0x41, 0x43, 0x59, 0x5f, 0x52, 0x45, 0x51, 0x55, + 0x49, 0x52, 0x45, 0x44, 0x10, 0x03, 0x22, 0x37, 0x0a, 0x08, 0x45, 0x6e, 0x75, 0x6d, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x15, 0x0a, 0x11, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, + 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x4f, 0x50, 0x45, + 0x4e, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x44, 0x10, 0x02, 0x22, + 0x56, 0x0a, 0x15, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x46, 0x69, 0x65, 0x6c, 0x64, + 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x45, 0x50, 0x45, + 0x41, 0x54, 0x45, 0x44, 0x5f, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x45, 0x4e, 0x43, 0x4f, 0x44, + 0x49, 0x4e, 0x47, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0a, 0x0a, + 0x06, 0x50, 0x41, 0x43, 0x4b, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x45, 0x58, 0x50, + 0x41, 0x4e, 0x44, 0x45, 0x44, 0x10, 0x02, 0x22, 0x49, 0x0a, 0x0e, 0x55, 0x74, 0x66, 0x38, 0x56, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x17, 0x55, 0x54, 0x46, + 0x38, 0x5f, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x4b, + 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x56, 0x45, 0x52, 0x49, 0x46, 0x59, + 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x03, 0x22, 0x04, 0x08, 0x01, + 0x10, 0x01, 0x22, 0x53, 0x0a, 0x0f, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x45, 0x6e, 0x63, + 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x1c, 0x0a, 0x18, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, + 0x5f, 0x45, 0x4e, 0x43, 0x4f, 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, + 0x4e, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x45, 0x4e, 0x47, 0x54, 0x48, 0x5f, 0x50, 0x52, + 0x45, 0x46, 0x49, 0x58, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x44, 0x45, 0x4c, 0x49, + 0x4d, 0x49, 0x54, 0x45, 0x44, 0x10, 0x02, 0x22, 0x48, 0x0a, 0x0a, 0x4a, 0x73, 0x6f, 0x6e, 0x46, + 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x17, 0x0a, 0x13, 0x4a, 0x53, 0x4f, 0x4e, 0x5f, 0x46, 0x4f, + 0x52, 0x4d, 0x41, 0x54, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x09, + 0x0a, 0x05, 0x41, 0x4c, 0x4c, 0x4f, 0x57, 0x10, 0x01, 0x12, 0x16, 0x0a, 0x12, 0x4c, 0x45, 0x47, + 0x41, 0x43, 0x59, 0x5f, 0x42, 0x45, 0x53, 0x54, 0x5f, 0x45, 0x46, 0x46, 0x4f, 0x52, 0x54, 0x10, + 0x02, 0x2a, 0x06, 0x08, 0xe8, 0x07, 0x10, 0x8b, 0x4e, 0x2a, 0x06, 0x08, 0x8b, 0x4e, 0x10, 0x90, + 0x4e, 0x2a, 0x06, 0x08, 0x90, 0x4e, 0x10, 0x91, 0x4e, 0x4a, 0x06, 0x08, 0xe7, 0x07, 0x10, 0xe8, + 0x07, 0x22, 0xef, 0x03, 0x0a, 0x12, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, + 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x58, 0x0a, 0x08, 0x64, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3c, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x65, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x2e, + 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x45, 0x64, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x52, 0x08, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, + 0x74, 0x73, 0x12, 0x41, 0x0a, 0x0f, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x5f, 0x65, 0x64, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x64, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x45, 0x64, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x41, 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, + 0x5f, 0x65, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x45, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, + 0x6d, 0x45, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0xf8, 0x01, 0x0a, 0x18, 0x46, 0x65, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x45, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, + 0x66, 0x61, 0x75, 0x6c, 0x74, 0x12, 0x32, 0x0a, 0x07, 0x65, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x07, 0x65, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x4e, 0x0a, 0x14, 0x6f, 0x76, 0x65, + 0x72, 0x72, 0x69, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x53, 0x65, 0x74, 0x52, 0x13, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x61, 0x62, 0x6c, + 0x65, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x42, 0x0a, 0x0e, 0x66, 0x69, 0x78, + 0x65, 0x64, 0x5f, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x52, 0x0d, + 0x66, 0x69, 0x78, 0x65, 0x64, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x4a, 0x04, 0x08, + 0x01, 0x10, 0x02, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x73, 0x22, 0xb5, 0x02, 0x0a, 0x0e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, + 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x44, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x43, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0xce, 0x01, 0x0a, + 0x08, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x04, 0x70, 0x61, 0x74, + 0x68, 0x18, 0x01, 0x20, 0x03, 0x28, 0x05, 0x42, 0x02, 0x10, 0x01, 0x52, 0x04, 0x70, 0x61, 0x74, + 0x68, 0x12, 0x16, 0x0a, 0x04, 0x73, 0x70, 0x61, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x05, 0x42, + 0x02, 0x10, 0x01, 0x52, 0x04, 0x73, 0x70, 0x61, 0x6e, 0x12, 0x29, 0x0a, 0x10, 0x6c, 0x65, 0x61, + 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0f, 0x6c, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x74, 0x72, 0x61, 0x69, 0x6c, 0x69, 0x6e, 0x67, + 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x10, 0x74, 0x72, 0x61, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x12, 0x3a, 0x0a, 0x19, 0x6c, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x64, 0x65, 0x74, + 0x61, 0x63, 0x68, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x06, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x17, 0x6c, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x74, + 0x61, 0x63, 0x68, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2a, 0x0c, 0x08, + 0x80, 0xec, 0xca, 0xff, 0x01, 0x10, 0x81, 0xec, 0xca, 0xff, 0x01, 0x22, 0xd0, 0x02, 0x0a, 0x11, + 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, + 0x6f, 0x12, 0x4d, 0x0a, 0x0a, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, + 0x64, 0x43, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x1a, 0xeb, 0x01, 0x0a, 0x0a, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x16, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x03, 0x28, 0x05, 0x42, 0x02, 0x10, + 0x01, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x65, 0x67, 0x69, + 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x12, 0x10, + 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x65, 0x6e, 0x64, + 0x12, 0x52, 0x0a, 0x08, 0x73, 0x65, 0x6d, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x36, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x43, 0x6f, + 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x2e, 0x53, 0x65, 0x6d, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x52, 0x08, 0x73, 0x65, 0x6d, 0x61, + 0x6e, 0x74, 0x69, 0x63, 0x22, 0x28, 0x0a, 0x08, 0x53, 0x65, 0x6d, 0x61, 0x6e, 0x74, 0x69, 0x63, + 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x53, 0x45, + 0x54, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x4c, 0x49, 0x41, 0x53, 0x10, 0x02, 0x2a, 0xa7, + 0x02, 0x0a, 0x07, 0x45, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x13, 0x0a, 0x0f, 0x45, 0x44, + 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, + 0x13, 0x0a, 0x0e, 0x45, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4c, 0x45, 0x47, 0x41, 0x43, + 0x59, 0x10, 0x84, 0x07, 0x12, 0x13, 0x0a, 0x0e, 0x45, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, + 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x32, 0x10, 0xe6, 0x07, 0x12, 0x13, 0x0a, 0x0e, 0x45, 0x44, 0x49, + 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x33, 0x10, 0xe7, 0x07, 0x12, 0x11, + 0x0a, 0x0c, 0x45, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x32, 0x30, 0x32, 0x33, 0x10, 0xe8, + 0x07, 0x12, 0x11, 0x0a, 0x0c, 0x45, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x32, 0x30, 0x32, + 0x34, 0x10, 0xe9, 0x07, 0x12, 0x17, 0x0a, 0x13, 0x45, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, + 0x31, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x01, 0x12, 0x17, 0x0a, + 0x13, 0x45, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x32, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x5f, + 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x02, 0x12, 0x1d, 0x0a, 0x17, 0x45, 0x44, 0x49, 0x54, 0x49, 0x4f, + 0x4e, 0x5f, 0x39, 0x39, 0x39, 0x39, 0x37, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x4f, 0x4e, 0x4c, + 0x59, 0x10, 0x9d, 0x8d, 0x06, 0x12, 0x1d, 0x0a, 0x17, 0x45, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, + 0x5f, 0x39, 0x39, 0x39, 0x39, 0x38, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x4f, 0x4e, 0x4c, 0x59, + 0x10, 0x9e, 0x8d, 0x06, 0x12, 0x1d, 0x0a, 0x17, 0x45, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, + 0x39, 0x39, 0x39, 0x39, 0x39, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x4f, 0x4e, 0x4c, 0x59, 0x10, + 0x9f, 0x8d, 0x06, 0x12, 0x13, 0x0a, 0x0b, 0x45, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4d, + 0x41, 0x58, 0x10, 0xff, 0xff, 0xff, 0xff, 0x07, 0x42, 0x7e, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x42, + 0x10, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, + 0x73, 0x48, 0x01, 0x5a, 0x2d, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, + 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, + 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, + 0x70, 0x62, 0xf8, 0x01, 0x01, 0xa2, 0x02, 0x03, 0x47, 0x50, 0x42, 0xaa, 0x02, 0x1a, 0x47, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x52, 0x65, + 0x66, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, +}) var ( file_google_protobuf_descriptor_proto_rawDescOnce sync.Once - file_google_protobuf_descriptor_proto_rawDescData = file_google_protobuf_descriptor_proto_rawDesc + file_google_protobuf_descriptor_proto_rawDescData []byte ) func file_google_protobuf_descriptor_proto_rawDescGZIP() []byte { file_google_protobuf_descriptor_proto_rawDescOnce.Do(func() { - file_google_protobuf_descriptor_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_protobuf_descriptor_proto_rawDescData) + file_google_protobuf_descriptor_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_google_protobuf_descriptor_proto_rawDesc), len(file_google_protobuf_descriptor_proto_rawDesc))) }) return file_google_protobuf_descriptor_proto_rawDescData } @@ -5323,7 +5293,7 @@ func file_google_protobuf_descriptor_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_google_protobuf_descriptor_proto_rawDesc, + RawDescriptor: unsafe.Slice(unsafe.StringData(file_google_protobuf_descriptor_proto_rawDesc), len(file_google_protobuf_descriptor_proto_rawDesc)), NumEnums: 17, NumMessages: 33, NumExtensions: 0, @@ -5335,7 +5305,6 @@ func file_google_protobuf_descriptor_proto_init() { MessageInfos: file_google_protobuf_descriptor_proto_msgTypes, }.Build() File_google_protobuf_descriptor_proto = out.File - file_google_protobuf_descriptor_proto_rawDesc = nil file_google_protobuf_descriptor_proto_goTypes = nil file_google_protobuf_descriptor_proto_depIdxs = nil } diff --git a/go-controller/vendor/google.golang.org/protobuf/types/gofeaturespb/go_features.pb.go b/go-controller/vendor/google.golang.org/protobuf/types/gofeaturespb/go_features.pb.go deleted file mode 100644 index c7e860fcd6..0000000000 --- a/go-controller/vendor/google.golang.org/protobuf/types/gofeaturespb/go_features.pb.go +++ /dev/null @@ -1,165 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2023 Google Inc. All rights reserved. -// -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file or at -// https://developers.google.com/open-source/licenses/bsd - -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: google/protobuf/go_features.proto - -package gofeaturespb - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - descriptorpb "google.golang.org/protobuf/types/descriptorpb" - reflect "reflect" - sync "sync" -) - -type GoFeatures struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Whether or not to generate the deprecated UnmarshalJSON method for enums. - LegacyUnmarshalJsonEnum *bool `protobuf:"varint,1,opt,name=legacy_unmarshal_json_enum,json=legacyUnmarshalJsonEnum" json:"legacy_unmarshal_json_enum,omitempty"` -} - -func (x *GoFeatures) Reset() { - *x = GoFeatures{} - mi := &file_google_protobuf_go_features_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *GoFeatures) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GoFeatures) ProtoMessage() {} - -func (x *GoFeatures) ProtoReflect() protoreflect.Message { - mi := &file_google_protobuf_go_features_proto_msgTypes[0] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GoFeatures.ProtoReflect.Descriptor instead. -func (*GoFeatures) Descriptor() ([]byte, []int) { - return file_google_protobuf_go_features_proto_rawDescGZIP(), []int{0} -} - -func (x *GoFeatures) GetLegacyUnmarshalJsonEnum() bool { - if x != nil && x.LegacyUnmarshalJsonEnum != nil { - return *x.LegacyUnmarshalJsonEnum - } - return false -} - -var file_google_protobuf_go_features_proto_extTypes = []protoimpl.ExtensionInfo{ - { - ExtendedType: (*descriptorpb.FeatureSet)(nil), - ExtensionType: (*GoFeatures)(nil), - Field: 1002, - Name: "pb.go", - Tag: "bytes,1002,opt,name=go", - Filename: "google/protobuf/go_features.proto", - }, -} - -// Extension fields to descriptorpb.FeatureSet. -var ( - // optional pb.GoFeatures go = 1002; - E_Go = &file_google_protobuf_go_features_proto_extTypes[0] -) - -var File_google_protobuf_go_features_proto protoreflect.FileDescriptor - -var file_google_protobuf_go_features_proto_rawDesc = []byte{ - 0x0a, 0x21, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2f, 0x67, 0x6f, 0x5f, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x12, 0x02, 0x70, 0x62, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, - 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xcd, 0x01, 0x0a, 0x0a, 0x47, 0x6f, - 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0xbe, 0x01, 0x0a, 0x1a, 0x6c, 0x65, 0x67, - 0x61, 0x63, 0x79, 0x5f, 0x75, 0x6e, 0x6d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x5f, 0x6a, 0x73, - 0x6f, 0x6e, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x42, 0x80, 0x01, - 0x88, 0x01, 0x01, 0x98, 0x01, 0x06, 0x98, 0x01, 0x01, 0xa2, 0x01, 0x09, 0x12, 0x04, 0x74, 0x72, - 0x75, 0x65, 0x18, 0x84, 0x07, 0xa2, 0x01, 0x0a, 0x12, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x18, - 0xe7, 0x07, 0xb2, 0x01, 0x5b, 0x08, 0xe8, 0x07, 0x10, 0xe8, 0x07, 0x1a, 0x53, 0x54, 0x68, 0x65, - 0x20, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x20, 0x55, 0x6e, 0x6d, 0x61, 0x72, 0x73, 0x68, 0x61, - 0x6c, 0x4a, 0x53, 0x4f, 0x4e, 0x20, 0x41, 0x50, 0x49, 0x20, 0x69, 0x73, 0x20, 0x64, 0x65, 0x70, - 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x77, 0x69, 0x6c, 0x6c, - 0x20, 0x62, 0x65, 0x20, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x61, - 0x20, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x20, 0x65, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2e, - 0x52, 0x17, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x55, 0x6e, 0x6d, 0x61, 0x72, 0x73, 0x68, 0x61, - 0x6c, 0x4a, 0x73, 0x6f, 0x6e, 0x45, 0x6e, 0x75, 0x6d, 0x3a, 0x3c, 0x0a, 0x02, 0x67, 0x6f, 0x12, - 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x65, 0x74, 0x18, 0xea, 0x07, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x6f, 0x46, 0x65, 0x61, 0x74, 0x75, - 0x72, 0x65, 0x73, 0x52, 0x02, 0x67, 0x6f, 0x42, 0x2f, 0x5a, 0x2d, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x67, 0x6f, 0x66, 0x65, - 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x70, 0x62, -} - -var ( - file_google_protobuf_go_features_proto_rawDescOnce sync.Once - file_google_protobuf_go_features_proto_rawDescData = file_google_protobuf_go_features_proto_rawDesc -) - -func file_google_protobuf_go_features_proto_rawDescGZIP() []byte { - file_google_protobuf_go_features_proto_rawDescOnce.Do(func() { - file_google_protobuf_go_features_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_protobuf_go_features_proto_rawDescData) - }) - return file_google_protobuf_go_features_proto_rawDescData -} - -var file_google_protobuf_go_features_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_google_protobuf_go_features_proto_goTypes = []any{ - (*GoFeatures)(nil), // 0: pb.GoFeatures - (*descriptorpb.FeatureSet)(nil), // 1: google.protobuf.FeatureSet -} -var file_google_protobuf_go_features_proto_depIdxs = []int32{ - 1, // 0: pb.go:extendee -> google.protobuf.FeatureSet - 0, // 1: pb.go:type_name -> pb.GoFeatures - 2, // [2:2] is the sub-list for method output_type - 2, // [2:2] is the sub-list for method input_type - 1, // [1:2] is the sub-list for extension type_name - 0, // [0:1] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_google_protobuf_go_features_proto_init() } -func file_google_protobuf_go_features_proto_init() { - if File_google_protobuf_go_features_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_google_protobuf_go_features_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 1, - NumServices: 0, - }, - GoTypes: file_google_protobuf_go_features_proto_goTypes, - DependencyIndexes: file_google_protobuf_go_features_proto_depIdxs, - MessageInfos: file_google_protobuf_go_features_proto_msgTypes, - ExtensionInfos: file_google_protobuf_go_features_proto_extTypes, - }.Build() - File_google_protobuf_go_features_proto = out.File - file_google_protobuf_go_features_proto_rawDesc = nil - file_google_protobuf_go_features_proto_goTypes = nil - file_google_protobuf_go_features_proto_depIdxs = nil -} diff --git a/go-controller/vendor/google.golang.org/protobuf/types/known/anypb/any.pb.go b/go-controller/vendor/google.golang.org/protobuf/types/known/anypb/any.pb.go index 87da199a38..497da66e91 100644 --- a/go-controller/vendor/google.golang.org/protobuf/types/known/anypb/any.pb.go +++ b/go-controller/vendor/google.golang.org/protobuf/types/known/anypb/any.pb.go @@ -122,6 +122,7 @@ import ( reflect "reflect" strings "strings" sync "sync" + unsafe "unsafe" ) // `Any` contains an arbitrary serialized protocol buffer message along with a @@ -210,10 +211,7 @@ import ( // "value": "1.212s" // } type Any struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` // A URL/resource name that uniquely identifies the type of the serialized // protocol buffer message. This string must contain at least // one "/" character. The last segment of the URL's path must represent @@ -244,7 +242,9 @@ type Any struct { // used with implementation specific semantics. TypeUrl string `protobuf:"bytes,1,opt,name=type_url,json=typeUrl,proto3" json:"type_url,omitempty"` // Must be a valid serialized protocol buffer of the above specified type. - Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } // New marshals src into a new Any instance. @@ -412,7 +412,7 @@ func (x *Any) GetValue() []byte { var File_google_protobuf_any_proto protoreflect.FileDescriptor -var file_google_protobuf_any_proto_rawDesc = []byte{ +var file_google_protobuf_any_proto_rawDesc = string([]byte{ 0x0a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x22, 0x36, 0x0a, 0x03, @@ -428,16 +428,16 @@ var file_google_protobuf_any_proto_rawDesc = []byte{ 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x57, 0x65, 0x6c, 0x6c, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} +}) var ( file_google_protobuf_any_proto_rawDescOnce sync.Once - file_google_protobuf_any_proto_rawDescData = file_google_protobuf_any_proto_rawDesc + file_google_protobuf_any_proto_rawDescData []byte ) func file_google_protobuf_any_proto_rawDescGZIP() []byte { file_google_protobuf_any_proto_rawDescOnce.Do(func() { - file_google_protobuf_any_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_protobuf_any_proto_rawDescData) + file_google_protobuf_any_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_google_protobuf_any_proto_rawDesc), len(file_google_protobuf_any_proto_rawDesc))) }) return file_google_protobuf_any_proto_rawDescData } @@ -463,7 +463,7 @@ func file_google_protobuf_any_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_google_protobuf_any_proto_rawDesc, + RawDescriptor: unsafe.Slice(unsafe.StringData(file_google_protobuf_any_proto_rawDesc), len(file_google_protobuf_any_proto_rawDesc)), NumEnums: 0, NumMessages: 1, NumExtensions: 0, @@ -474,7 +474,6 @@ func file_google_protobuf_any_proto_init() { MessageInfos: file_google_protobuf_any_proto_msgTypes, }.Build() File_google_protobuf_any_proto = out.File - file_google_protobuf_any_proto_rawDesc = nil file_google_protobuf_any_proto_goTypes = nil file_google_protobuf_any_proto_depIdxs = nil } diff --git a/go-controller/vendor/google.golang.org/protobuf/types/known/durationpb/duration.pb.go b/go-controller/vendor/google.golang.org/protobuf/types/known/durationpb/duration.pb.go index b99d4d2410..193880d181 100644 --- a/go-controller/vendor/google.golang.org/protobuf/types/known/durationpb/duration.pb.go +++ b/go-controller/vendor/google.golang.org/protobuf/types/known/durationpb/duration.pb.go @@ -80,6 +80,7 @@ import ( reflect "reflect" sync "sync" time "time" + unsafe "unsafe" ) // A Duration represents a signed, fixed-length span of time represented @@ -141,10 +142,7 @@ import ( // be expressed in JSON format as "3.000000001s", and 3 seconds and 1 // microsecond should be expressed in JSON format as "3.000001s". type Duration struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` // Signed seconds of the span of time. Must be from -315,576,000,000 // to +315,576,000,000 inclusive. Note: these bounds are computed from: // 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years @@ -155,7 +153,9 @@ type Duration struct { // of one second or more, a non-zero value for the `nanos` field must be // of the same sign as the `seconds` field. Must be from -999,999,999 // to +999,999,999 inclusive. - Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"` + Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } // New constructs a new Duration from the provided time.Duration. @@ -289,7 +289,7 @@ func (x *Duration) GetNanos() int32 { var File_google_protobuf_duration_proto protoreflect.FileDescriptor -var file_google_protobuf_duration_proto_rawDesc = []byte{ +var file_google_protobuf_duration_proto_rawDesc = string([]byte{ 0x0a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, @@ -306,16 +306,16 @@ var file_google_protobuf_duration_proto_rawDesc = []byte{ 0x50, 0x42, 0xaa, 0x02, 0x1e, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x57, 0x65, 0x6c, 0x6c, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} +}) var ( file_google_protobuf_duration_proto_rawDescOnce sync.Once - file_google_protobuf_duration_proto_rawDescData = file_google_protobuf_duration_proto_rawDesc + file_google_protobuf_duration_proto_rawDescData []byte ) func file_google_protobuf_duration_proto_rawDescGZIP() []byte { file_google_protobuf_duration_proto_rawDescOnce.Do(func() { - file_google_protobuf_duration_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_protobuf_duration_proto_rawDescData) + file_google_protobuf_duration_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_google_protobuf_duration_proto_rawDesc), len(file_google_protobuf_duration_proto_rawDesc))) }) return file_google_protobuf_duration_proto_rawDescData } @@ -341,7 +341,7 @@ func file_google_protobuf_duration_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_google_protobuf_duration_proto_rawDesc, + RawDescriptor: unsafe.Slice(unsafe.StringData(file_google_protobuf_duration_proto_rawDesc), len(file_google_protobuf_duration_proto_rawDesc)), NumEnums: 0, NumMessages: 1, NumExtensions: 0, @@ -352,7 +352,6 @@ func file_google_protobuf_duration_proto_init() { MessageInfos: file_google_protobuf_duration_proto_msgTypes, }.Build() File_google_protobuf_duration_proto = out.File - file_google_protobuf_duration_proto_rawDesc = nil file_google_protobuf_duration_proto_goTypes = nil file_google_protobuf_duration_proto_depIdxs = nil } diff --git a/go-controller/vendor/google.golang.org/protobuf/types/known/timestamppb/timestamp.pb.go b/go-controller/vendor/google.golang.org/protobuf/types/known/timestamppb/timestamp.pb.go index 0d20722d70..00ac835c0b 100644 --- a/go-controller/vendor/google.golang.org/protobuf/types/known/timestamppb/timestamp.pb.go +++ b/go-controller/vendor/google.golang.org/protobuf/types/known/timestamppb/timestamp.pb.go @@ -78,6 +78,7 @@ import ( reflect "reflect" sync "sync" time "time" + unsafe "unsafe" ) // A Timestamp represents a point in time independent of any time zone or local @@ -170,10 +171,7 @@ import ( // http://joda-time.sourceforge.net/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime() // ) to obtain a formatter capable of generating timestamps in this format. type Timestamp struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` // Represents seconds of UTC time since Unix epoch // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to // 9999-12-31T23:59:59Z inclusive. @@ -182,7 +180,9 @@ type Timestamp struct { // second values with fractions must still have non-negative nanos values // that count forward in time. Must be from 0 to 999,999,999 // inclusive. - Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"` + Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } // Now constructs a new Timestamp from the current time. @@ -298,7 +298,7 @@ func (x *Timestamp) GetNanos() int32 { var File_google_protobuf_timestamp_proto protoreflect.FileDescriptor -var file_google_protobuf_timestamp_proto_rawDesc = []byte{ +var file_google_protobuf_timestamp_proto_rawDesc = string([]byte{ 0x0a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, @@ -315,16 +315,16 @@ var file_google_protobuf_timestamp_proto_rawDesc = []byte{ 0xa2, 0x02, 0x03, 0x47, 0x50, 0x42, 0xaa, 0x02, 0x1e, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x57, 0x65, 0x6c, 0x6c, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} +}) var ( file_google_protobuf_timestamp_proto_rawDescOnce sync.Once - file_google_protobuf_timestamp_proto_rawDescData = file_google_protobuf_timestamp_proto_rawDesc + file_google_protobuf_timestamp_proto_rawDescData []byte ) func file_google_protobuf_timestamp_proto_rawDescGZIP() []byte { file_google_protobuf_timestamp_proto_rawDescOnce.Do(func() { - file_google_protobuf_timestamp_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_protobuf_timestamp_proto_rawDescData) + file_google_protobuf_timestamp_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_google_protobuf_timestamp_proto_rawDesc), len(file_google_protobuf_timestamp_proto_rawDesc))) }) return file_google_protobuf_timestamp_proto_rawDescData } @@ -350,7 +350,7 @@ func file_google_protobuf_timestamp_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_google_protobuf_timestamp_proto_rawDesc, + RawDescriptor: unsafe.Slice(unsafe.StringData(file_google_protobuf_timestamp_proto_rawDesc), len(file_google_protobuf_timestamp_proto_rawDesc)), NumEnums: 0, NumMessages: 1, NumExtensions: 0, @@ -361,7 +361,6 @@ func file_google_protobuf_timestamp_proto_init() { MessageInfos: file_google_protobuf_timestamp_proto_msgTypes, }.Build() File_google_protobuf_timestamp_proto = out.File - file_google_protobuf_timestamp_proto_rawDesc = nil file_google_protobuf_timestamp_proto_goTypes = nil file_google_protobuf_timestamp_proto_depIdxs = nil } diff --git a/go-controller/vendor/k8s.io/api/admission/v1/doc.go b/go-controller/vendor/k8s.io/api/admission/v1/doc.go index e7df9f629c..cab6528214 100644 --- a/go-controller/vendor/k8s.io/api/admission/v1/doc.go +++ b/go-controller/vendor/k8s.io/api/admission/v1/doc.go @@ -20,4 +20,4 @@ limitations under the License. // +k8s:prerelease-lifecycle-gen=true // +groupName=admission.k8s.io -package v1 // import "k8s.io/api/admission/v1" +package v1 diff --git a/go-controller/vendor/k8s.io/api/admission/v1beta1/doc.go b/go-controller/vendor/k8s.io/api/admission/v1beta1/doc.go index a5669022a0..447495684e 100644 --- a/go-controller/vendor/k8s.io/api/admission/v1beta1/doc.go +++ b/go-controller/vendor/k8s.io/api/admission/v1beta1/doc.go @@ -21,4 +21,4 @@ limitations under the License. // +groupName=admission.k8s.io -package v1beta1 // import "k8s.io/api/admission/v1beta1" +package v1beta1 diff --git a/go-controller/vendor/k8s.io/api/admissionregistration/v1/doc.go b/go-controller/vendor/k8s.io/api/admissionregistration/v1/doc.go index ca0086188a..ec0ebb9c49 100644 --- a/go-controller/vendor/k8s.io/api/admissionregistration/v1/doc.go +++ b/go-controller/vendor/k8s.io/api/admissionregistration/v1/doc.go @@ -24,4 +24,4 @@ limitations under the License. // AdmissionConfiguration and AdmissionPluginConfiguration are legacy static admission plugin configuration // MutatingWebhookConfiguration and ValidatingWebhookConfiguration are for the // new dynamic admission controller configuration. -package v1 // import "k8s.io/api/admissionregistration/v1" +package v1 diff --git a/go-controller/vendor/k8s.io/api/admissionregistration/v1alpha1/doc.go b/go-controller/vendor/k8s.io/api/admissionregistration/v1alpha1/doc.go index 98066211d8..344af9ae09 100644 --- a/go-controller/vendor/k8s.io/api/admissionregistration/v1alpha1/doc.go +++ b/go-controller/vendor/k8s.io/api/admissionregistration/v1alpha1/doc.go @@ -21,4 +21,4 @@ limitations under the License. // +groupName=admissionregistration.k8s.io // Package v1alpha1 is the v1alpha1 version of the API. -package v1alpha1 // import "k8s.io/api/admissionregistration/v1alpha1" +package v1alpha1 diff --git a/go-controller/vendor/k8s.io/api/admissionregistration/v1alpha1/generated.proto b/go-controller/vendor/k8s.io/api/admissionregistration/v1alpha1/generated.proto index 88344ce87a..d23f21cc84 100644 --- a/go-controller/vendor/k8s.io/api/admissionregistration/v1alpha1/generated.proto +++ b/go-controller/vendor/k8s.io/api/admissionregistration/v1alpha1/generated.proto @@ -272,9 +272,9 @@ message MatchResources { // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector namespaceSelector = 1; - // ObjectSelector decides whether to run the validation based on if the + // ObjectSelector decides whether to run the policy based on if the // object has matching labels. objectSelector is evaluated against both - // the oldObject and newObject that would be sent to the cel validation, and + // the oldObject and newObject that would be sent to the policy's expression (CEL), and // is considered to match if either object matches the selector. A null // object (oldObject in the case of create, or newObject in the case of // delete) or an object that cannot have labels (like a @@ -286,13 +286,13 @@ message MatchResources { // +optional optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector objectSelector = 2; - // ResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy matches. + // ResourceRules describes what operations on what resources/subresources the admission policy matches. // The policy cares about an operation if it matches _any_ Rule. // +listType=atomic // +optional repeated NamedRuleWithOperations resourceRules = 3; - // ExcludeResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy should not care about. + // ExcludeResourceRules describes what operations on what resources/subresources the policy should not care about. // The exclude rules take precedence over include rules (if a resource matches both, it is excluded) // +listType=atomic // +optional @@ -304,12 +304,13 @@ message MatchResources { // - Exact: match a request only if it exactly matches a specified rule. // For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, // but "rules" only included `apiGroups:["apps"], apiVersions:["v1"], resources: ["deployments"]`, - // a request to apps/v1beta1 or extensions/v1beta1 would not be sent to the ValidatingAdmissionPolicy. + // the admission policy does not consider requests to apps/v1beta1 or extensions/v1beta1 API groups. // // - Equivalent: match a request if modifies a resource listed in rules, even via another API group or version. // For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, // and "rules" only included `apiGroups:["apps"], apiVersions:["v1"], resources: ["deployments"]`, - // a request to apps/v1beta1 or extensions/v1beta1 would be converted to apps/v1 and sent to the ValidatingAdmissionPolicy. + // the admission policy **does** consider requests made to apps/v1beta1 or extensions/v1beta1 + // API groups. The API server translates the request to a matched resource API if necessary. // // Defaults to "Equivalent" // +optional diff --git a/go-controller/vendor/k8s.io/api/admissionregistration/v1alpha1/types.go b/go-controller/vendor/k8s.io/api/admissionregistration/v1alpha1/types.go index ee50fbe2d4..f183498a55 100644 --- a/go-controller/vendor/k8s.io/api/admissionregistration/v1alpha1/types.go +++ b/go-controller/vendor/k8s.io/api/admissionregistration/v1alpha1/types.go @@ -56,9 +56,9 @@ const ( type FailurePolicyType string const ( - // Ignore means that an error calling the webhook is ignored. + // Ignore means that an error calling the admission webhook or admission policy is ignored. Ignore FailurePolicyType = "Ignore" - // Fail means that an error calling the webhook causes the admission to fail. + // Fail means that an error calling the admission webhook or admission policy causes resource admission to fail. Fail FailurePolicyType = "Fail" ) @@ -67,9 +67,11 @@ const ( type MatchPolicyType string const ( - // Exact means requests should only be sent to the webhook if they exactly match a given rule. + // Exact means requests should only be sent to the admission webhook or admission policy if they exactly match a given rule. Exact MatchPolicyType = "Exact" - // Equivalent means requests should be sent to the webhook if they modify a resource listed in rules via another API group or version. + // Equivalent means requests should be sent to the admission webhook or admission policy if they modify a resource listed + // in rules via an equivalent API group or version. For example, `autoscaling/v1` and `autoscaling/v2` + // HorizontalPodAutoscalers are equivalent: the same set of resources appear via both APIs. Equivalent MatchPolicyType = "Equivalent" ) @@ -577,9 +579,9 @@ type MatchResources struct { // Default to the empty LabelSelector, which matches everything. // +optional NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty" protobuf:"bytes,1,opt,name=namespaceSelector"` - // ObjectSelector decides whether to run the validation based on if the + // ObjectSelector decides whether to run the policy based on if the // object has matching labels. objectSelector is evaluated against both - // the oldObject and newObject that would be sent to the cel validation, and + // the oldObject and newObject that would be sent to the policy's expression (CEL), and // is considered to match if either object matches the selector. A null // object (oldObject in the case of create, or newObject in the case of // delete) or an object that cannot have labels (like a @@ -590,12 +592,12 @@ type MatchResources struct { // Default to the empty LabelSelector, which matches everything. // +optional ObjectSelector *metav1.LabelSelector `json:"objectSelector,omitempty" protobuf:"bytes,2,opt,name=objectSelector"` - // ResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy matches. + // ResourceRules describes what operations on what resources/subresources the admission policy matches. // The policy cares about an operation if it matches _any_ Rule. // +listType=atomic // +optional ResourceRules []NamedRuleWithOperations `json:"resourceRules,omitempty" protobuf:"bytes,3,rep,name=resourceRules"` - // ExcludeResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy should not care about. + // ExcludeResourceRules describes what operations on what resources/subresources the policy should not care about. // The exclude rules take precedence over include rules (if a resource matches both, it is excluded) // +listType=atomic // +optional @@ -606,12 +608,13 @@ type MatchResources struct { // - Exact: match a request only if it exactly matches a specified rule. // For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, // but "rules" only included `apiGroups:["apps"], apiVersions:["v1"], resources: ["deployments"]`, - // a request to apps/v1beta1 or extensions/v1beta1 would not be sent to the ValidatingAdmissionPolicy. + // the admission policy does not consider requests to apps/v1beta1 or extensions/v1beta1 API groups. // // - Equivalent: match a request if modifies a resource listed in rules, even via another API group or version. // For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, // and "rules" only included `apiGroups:["apps"], apiVersions:["v1"], resources: ["deployments"]`, - // a request to apps/v1beta1 or extensions/v1beta1 would be converted to apps/v1 and sent to the ValidatingAdmissionPolicy. + // the admission policy **does** consider requests made to apps/v1beta1 or extensions/v1beta1 + // API groups. The API server translates the request to a matched resource API if necessary. // // Defaults to "Equivalent" // +optional diff --git a/go-controller/vendor/k8s.io/api/admissionregistration/v1alpha1/types_swagger_doc_generated.go b/go-controller/vendor/k8s.io/api/admissionregistration/v1alpha1/types_swagger_doc_generated.go index 32222a81b8..116e56e065 100644 --- a/go-controller/vendor/k8s.io/api/admissionregistration/v1alpha1/types_swagger_doc_generated.go +++ b/go-controller/vendor/k8s.io/api/admissionregistration/v1alpha1/types_swagger_doc_generated.go @@ -68,10 +68,10 @@ func (JSONPatch) SwaggerDoc() map[string]string { var map_MatchResources = map[string]string{ "": "MatchResources decides whether to run the admission control policy on an object based on whether it meets the match criteria. The exclude rules take precedence over include rules (if a resource matches both, it is excluded)", "namespaceSelector": "NamespaceSelector decides whether to run the admission control policy on an object based on whether the namespace for that object matches the selector. If the object itself is a namespace, the matching is performed on object.metadata.labels. If the object is another cluster scoped resource, it never skips the policy.\n\nFor example, to run the webhook on any objects whose namespace is not associated with \"runlevel\" of \"0\" or \"1\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"runlevel\",\n \"operator\": \"NotIn\",\n \"values\": [\n \"0\",\n \"1\"\n ]\n }\n ]\n}\n\nIf instead you want to only run the policy on any objects whose namespace is associated with the \"environment\" of \"prod\" or \"staging\"; you will set the selector as follows: \"namespaceSelector\": {\n \"matchExpressions\": [\n {\n \"key\": \"environment\",\n \"operator\": \"In\",\n \"values\": [\n \"prod\",\n \"staging\"\n ]\n }\n ]\n}\n\nSee https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ for more examples of label selectors.\n\nDefault to the empty LabelSelector, which matches everything.", - "objectSelector": "ObjectSelector decides whether to run the validation based on if the object has matching labels. objectSelector is evaluated against both the oldObject and newObject that would be sent to the cel validation, and is considered to match if either object matches the selector. A null object (oldObject in the case of create, or newObject in the case of delete) or an object that cannot have labels (like a DeploymentRollback or a PodProxyOptions object) is not considered to match. Use the object selector only if the webhook is opt-in, because end users may skip the admission webhook by setting the labels. Default to the empty LabelSelector, which matches everything.", - "resourceRules": "ResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy matches. The policy cares about an operation if it matches _any_ Rule.", - "excludeResourceRules": "ExcludeResourceRules describes what operations on what resources/subresources the ValidatingAdmissionPolicy should not care about. The exclude rules take precedence over include rules (if a resource matches both, it is excluded)", - "matchPolicy": "matchPolicy defines how the \"MatchResources\" list is used to match incoming requests. Allowed values are \"Exact\" or \"Equivalent\".\n\n- Exact: match a request only if it exactly matches a specified rule. For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, but \"rules\" only included `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]`, a request to apps/v1beta1 or extensions/v1beta1 would not be sent to the ValidatingAdmissionPolicy.\n\n- Equivalent: match a request if modifies a resource listed in rules, even via another API group or version. For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, and \"rules\" only included `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]`, a request to apps/v1beta1 or extensions/v1beta1 would be converted to apps/v1 and sent to the ValidatingAdmissionPolicy.\n\nDefaults to \"Equivalent\"", + "objectSelector": "ObjectSelector decides whether to run the policy based on if the object has matching labels. objectSelector is evaluated against both the oldObject and newObject that would be sent to the policy's expression (CEL), and is considered to match if either object matches the selector. A null object (oldObject in the case of create, or newObject in the case of delete) or an object that cannot have labels (like a DeploymentRollback or a PodProxyOptions object) is not considered to match. Use the object selector only if the webhook is opt-in, because end users may skip the admission webhook by setting the labels. Default to the empty LabelSelector, which matches everything.", + "resourceRules": "ResourceRules describes what operations on what resources/subresources the admission policy matches. The policy cares about an operation if it matches _any_ Rule.", + "excludeResourceRules": "ExcludeResourceRules describes what operations on what resources/subresources the policy should not care about. The exclude rules take precedence over include rules (if a resource matches both, it is excluded)", + "matchPolicy": "matchPolicy defines how the \"MatchResources\" list is used to match incoming requests. Allowed values are \"Exact\" or \"Equivalent\".\n\n- Exact: match a request only if it exactly matches a specified rule. For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, but \"rules\" only included `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]`, the admission policy does not consider requests to apps/v1beta1 or extensions/v1beta1 API groups.\n\n- Equivalent: match a request if modifies a resource listed in rules, even via another API group or version. For example, if deployments can be modified via apps/v1, apps/v1beta1, and extensions/v1beta1, and \"rules\" only included `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]`, the admission policy **does** consider requests made to apps/v1beta1 or extensions/v1beta1 API groups. The API server translates the request to a matched resource API if necessary.\n\nDefaults to \"Equivalent\"", } func (MatchResources) SwaggerDoc() map[string]string { diff --git a/go-controller/vendor/k8s.io/api/admissionregistration/v1beta1/doc.go b/go-controller/vendor/k8s.io/api/admissionregistration/v1beta1/doc.go index 0095cb257a..40d8315738 100644 --- a/go-controller/vendor/k8s.io/api/admissionregistration/v1beta1/doc.go +++ b/go-controller/vendor/k8s.io/api/admissionregistration/v1beta1/doc.go @@ -24,4 +24,4 @@ limitations under the License. // AdmissionConfiguration and AdmissionPluginConfiguration are legacy static admission plugin configuration // MutatingWebhookConfiguration and ValidatingWebhookConfiguration are for the // new dynamic admission controller configuration. -package v1beta1 // import "k8s.io/api/admissionregistration/v1beta1" +package v1beta1 diff --git a/go-controller/vendor/k8s.io/api/apidiscovery/v2/doc.go b/go-controller/vendor/k8s.io/api/apidiscovery/v2/doc.go index 4f3ad5f139..f46d33e942 100644 --- a/go-controller/vendor/k8s.io/api/apidiscovery/v2/doc.go +++ b/go-controller/vendor/k8s.io/api/apidiscovery/v2/doc.go @@ -20,4 +20,4 @@ limitations under the License. // +k8s:prerelease-lifecycle-gen=true // +groupName=apidiscovery.k8s.io -package v2 // import "k8s.io/api/apidiscovery/v2" +package v2 diff --git a/go-controller/vendor/k8s.io/api/apidiscovery/v2beta1/doc.go b/go-controller/vendor/k8s.io/api/apidiscovery/v2beta1/doc.go index e85da226e0..d4fceab68d 100644 --- a/go-controller/vendor/k8s.io/api/apidiscovery/v2beta1/doc.go +++ b/go-controller/vendor/k8s.io/api/apidiscovery/v2beta1/doc.go @@ -21,4 +21,4 @@ limitations under the License. // +groupName=apidiscovery.k8s.io -package v2beta1 // import "k8s.io/api/apidiscovery/v2beta1" +package v2beta1 diff --git a/go-controller/vendor/k8s.io/api/apiserverinternal/v1alpha1/doc.go b/go-controller/vendor/k8s.io/api/apiserverinternal/v1alpha1/doc.go index a4da95d44d..867d741651 100644 --- a/go-controller/vendor/k8s.io/api/apiserverinternal/v1alpha1/doc.go +++ b/go-controller/vendor/k8s.io/api/apiserverinternal/v1alpha1/doc.go @@ -22,4 +22,4 @@ limitations under the License. // Package v1alpha1 contains the v1alpha1 version of the API used by the // apiservers themselves. -package v1alpha1 // import "k8s.io/api/apiserverinternal/v1alpha1" +package v1alpha1 diff --git a/go-controller/vendor/k8s.io/api/apps/v1/doc.go b/go-controller/vendor/k8s.io/api/apps/v1/doc.go index d189e860f2..51fe12c53d 100644 --- a/go-controller/vendor/k8s.io/api/apps/v1/doc.go +++ b/go-controller/vendor/k8s.io/api/apps/v1/doc.go @@ -19,4 +19,4 @@ limitations under the License. // +k8s:openapi-gen=true // +k8s:prerelease-lifecycle-gen=true -package v1 // import "k8s.io/api/apps/v1" +package v1 diff --git a/go-controller/vendor/k8s.io/api/apps/v1/generated.pb.go b/go-controller/vendor/k8s.io/api/apps/v1/generated.pb.go index ea62a099fe..eacc25931b 100644 --- a/go-controller/vendor/k8s.io/api/apps/v1/generated.pb.go +++ b/go-controller/vendor/k8s.io/api/apps/v1/generated.pb.go @@ -928,145 +928,147 @@ func init() { } var fileDescriptor_5b781835628d5338 = []byte{ - // 2194 bytes of a gzipped FileDescriptorProto + // 2225 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5a, 0xcd, 0x6f, 0x1b, 0xc7, - 0x15, 0xd7, 0xf2, 0x43, 0xa2, 0x86, 0x96, 0x64, 0x8f, 0x54, 0x89, 0xb1, 0x1b, 0xd2, 0xdd, 0xb8, - 0xb6, 0x12, 0xc7, 0x64, 0xed, 0x38, 0x41, 0xe0, 0x14, 0x09, 0x44, 0x2a, 0x4d, 0xd3, 0xe8, 0xab, - 0x43, 0xcb, 0x01, 0xdc, 0xb4, 0xe8, 0x68, 0x39, 0xa6, 0x36, 0xde, 0x2f, 0xec, 0x0e, 0x15, 0x0b, - 0xbd, 0x14, 0x05, 0x7a, 0xeb, 0xa1, 0x7f, 0x43, 0xff, 0x81, 0xa2, 0x28, 0x9a, 0x5b, 0x10, 0x04, - 0xbd, 0xf8, 0x52, 0x20, 0xe8, 0xa5, 0x39, 0x11, 0x35, 0x73, 0x2a, 0x8a, 0xde, 0xda, 0x8b, 0x2f, - 0x2d, 0x66, 0x76, 0xf6, 0x7b, 0x56, 0xa4, 0xe4, 0x58, 0x69, 0x82, 0xdc, 0xb8, 0x33, 0xbf, 0xf7, - 0xdb, 0x37, 0x33, 0xef, 0xcd, 0xfb, 0xcd, 0x2c, 0x81, 0x7a, 0xff, 0x55, 0xaf, 0xa9, 0xdb, 0x2d, - 0xec, 0xe8, 0x2d, 0xec, 0x38, 0x5e, 0xeb, 0xe0, 0x7a, 0xab, 0x4f, 0x2c, 0xe2, 0x62, 0x4a, 0x7a, - 0x4d, 0xc7, 0xb5, 0xa9, 0x0d, 0xa1, 0x8f, 0x69, 0x62, 0x47, 0x6f, 0x32, 0x4c, 0xf3, 0xe0, 0xfa, - 0xf9, 0x6b, 0x7d, 0x9d, 0xee, 0x0f, 0xf6, 0x9a, 0x9a, 0x6d, 0xb6, 0xfa, 0x76, 0xdf, 0x6e, 0x71, - 0xe8, 0xde, 0xe0, 0x1e, 0x7f, 0xe2, 0x0f, 0xfc, 0x97, 0x4f, 0x71, 0x3e, 0xfe, 0x1a, 0xcd, 0x76, - 0x89, 0xe4, 0x35, 0xe7, 0x6f, 0x46, 0x18, 0x13, 0x6b, 0xfb, 0xba, 0x45, 0xdc, 0xc3, 0x96, 0x73, - 0xbf, 0xcf, 0x1a, 0xbc, 0x96, 0x49, 0x28, 0x96, 0x59, 0xb5, 0xf2, 0xac, 0xdc, 0x81, 0x45, 0x75, - 0x93, 0x64, 0x0c, 0x5e, 0x19, 0x67, 0xe0, 0x69, 0xfb, 0xc4, 0xc4, 0x19, 0xbb, 0x97, 0xf2, 0xec, - 0x06, 0x54, 0x37, 0x5a, 0xba, 0x45, 0x3d, 0xea, 0xa6, 0x8d, 0xd4, 0xff, 0x28, 0x00, 0x76, 0x6c, - 0x8b, 0xba, 0xb6, 0x61, 0x10, 0x17, 0x91, 0x03, 0xdd, 0xd3, 0x6d, 0x0b, 0xfe, 0x1c, 0x54, 0xd8, - 0x78, 0x7a, 0x98, 0xe2, 0x9a, 0x72, 0x51, 0x59, 0xad, 0xde, 0xf8, 0x5e, 0x33, 0x9a, 0xe4, 0x90, - 0xbe, 0xe9, 0xdc, 0xef, 0xb3, 0x06, 0xaf, 0xc9, 0xd0, 0xcd, 0x83, 0xeb, 0xcd, 0xed, 0xbd, 0xf7, - 0x89, 0x46, 0x37, 0x09, 0xc5, 0x6d, 0xf8, 0x70, 0xd8, 0x98, 0x1a, 0x0d, 0x1b, 0x20, 0x6a, 0x43, - 0x21, 0x2b, 0xdc, 0x06, 0x25, 0xce, 0x5e, 0xe0, 0xec, 0xd7, 0x72, 0xd9, 0xc5, 0xa0, 0x9b, 0x08, - 0x7f, 0xf0, 0xe6, 0x03, 0x4a, 0x2c, 0xe6, 0x5e, 0xfb, 0x8c, 0xa0, 0x2e, 0xad, 0x63, 0x8a, 0x11, - 0x27, 0x82, 0x2f, 0x82, 0x8a, 0x2b, 0xdc, 0xaf, 0x15, 0x2f, 0x2a, 0xab, 0xc5, 0xf6, 0x59, 0x81, - 0xaa, 0x04, 0xc3, 0x42, 0x21, 0x42, 0xfd, 0xb3, 0x02, 0x96, 0xb3, 0xe3, 0xde, 0xd0, 0x3d, 0x0a, - 0xdf, 0xcb, 0x8c, 0xbd, 0x39, 0xd9, 0xd8, 0x99, 0x35, 0x1f, 0x79, 0xf8, 0xe2, 0xa0, 0x25, 0x36, - 0xee, 0x77, 0x40, 0x59, 0xa7, 0xc4, 0xf4, 0x6a, 0x85, 0x8b, 0xc5, 0xd5, 0xea, 0x8d, 0xcb, 0xcd, - 0x6c, 0xec, 0x36, 0xb3, 0x8e, 0xb5, 0xe7, 0x04, 0x65, 0xf9, 0x6d, 0x66, 0x8c, 0x7c, 0x0e, 0xf5, - 0xbf, 0x0a, 0x98, 0x5d, 0xc7, 0xc4, 0xb4, 0xad, 0x2e, 0xa1, 0xa7, 0xb0, 0x68, 0x1d, 0x50, 0xf2, - 0x1c, 0xa2, 0x89, 0x45, 0xfb, 0x8e, 0xcc, 0xf7, 0xd0, 0x9d, 0xae, 0x43, 0xb4, 0x68, 0xa1, 0xd8, - 0x13, 0xe2, 0xc6, 0xf0, 0x1d, 0x30, 0xed, 0x51, 0x4c, 0x07, 0x1e, 0x5f, 0xa6, 0xea, 0x8d, 0xe7, - 0x8e, 0xa6, 0xe1, 0xd0, 0xf6, 0xbc, 0x20, 0x9a, 0xf6, 0x9f, 0x91, 0xa0, 0x50, 0xff, 0x51, 0x00, - 0x30, 0xc4, 0x76, 0x6c, 0xab, 0xa7, 0x53, 0x16, 0xbf, 0xb7, 0x40, 0x89, 0x1e, 0x3a, 0x84, 0x4f, - 0xc3, 0x6c, 0xfb, 0x72, 0xe0, 0xc5, 0xed, 0x43, 0x87, 0x3c, 0x1e, 0x36, 0x96, 0xb3, 0x16, 0xac, - 0x07, 0x71, 0x1b, 0xb8, 0x11, 0xfa, 0x57, 0xe0, 0xd6, 0x37, 0x93, 0xaf, 0x7e, 0x3c, 0x6c, 0x48, - 0x36, 0x8b, 0x66, 0xc8, 0x94, 0x74, 0x10, 0x1e, 0x00, 0x68, 0x60, 0x8f, 0xde, 0x76, 0xb1, 0xe5, - 0xf9, 0x6f, 0xd2, 0x4d, 0x22, 0x46, 0xfe, 0xc2, 0x64, 0xcb, 0xc3, 0x2c, 0xda, 0xe7, 0x85, 0x17, - 0x70, 0x23, 0xc3, 0x86, 0x24, 0x6f, 0x80, 0x97, 0xc1, 0xb4, 0x4b, 0xb0, 0x67, 0x5b, 0xb5, 0x12, - 0x1f, 0x45, 0x38, 0x81, 0x88, 0xb7, 0x22, 0xd1, 0x0b, 0x9f, 0x07, 0x33, 0x26, 0xf1, 0x3c, 0xdc, - 0x27, 0xb5, 0x32, 0x07, 0x2e, 0x08, 0xe0, 0xcc, 0xa6, 0xdf, 0x8c, 0x82, 0x7e, 0xf5, 0x0f, 0x0a, - 0x98, 0x0b, 0x67, 0xee, 0x14, 0x52, 0xa5, 0x9d, 0x4c, 0x95, 0x67, 0x8f, 0x8c, 0x93, 0x9c, 0x0c, - 0xf9, 0xb8, 0x18, 0xf3, 0x99, 0x05, 0x21, 0xfc, 0x29, 0xa8, 0x78, 0xc4, 0x20, 0x1a, 0xb5, 0x5d, - 0xe1, 0xf3, 0x4b, 0x13, 0xfa, 0x8c, 0xf7, 0x88, 0xd1, 0x15, 0xa6, 0xed, 0x33, 0xcc, 0xe9, 0xe0, - 0x09, 0x85, 0x94, 0xf0, 0xc7, 0xa0, 0x42, 0x89, 0xe9, 0x18, 0x98, 0x12, 0x91, 0x26, 0x89, 0xf8, - 0x66, 0xe1, 0xc2, 0xc8, 0x76, 0xec, 0xde, 0x6d, 0x01, 0xe3, 0x89, 0x12, 0xce, 0x43, 0xd0, 0x8a, - 0x42, 0x1a, 0x78, 0x1f, 0xcc, 0x0f, 0x9c, 0x1e, 0x43, 0x52, 0xb6, 0x75, 0xf7, 0x0f, 0x45, 0xf8, - 0x5c, 0x3d, 0x72, 0x42, 0x76, 0x13, 0x26, 0xed, 0x65, 0xf1, 0x82, 0xf9, 0x64, 0x3b, 0x4a, 0x51, - 0xc3, 0x35, 0xb0, 0x60, 0xea, 0x16, 0x22, 0xb8, 0x77, 0xd8, 0x25, 0x9a, 0x6d, 0xf5, 0x3c, 0x1e, - 0x40, 0xe5, 0xf6, 0x8a, 0x20, 0x58, 0xd8, 0x4c, 0x76, 0xa3, 0x34, 0x1e, 0x6e, 0x80, 0xa5, 0x60, - 0x9f, 0xfd, 0xa1, 0xee, 0x51, 0xdb, 0x3d, 0xdc, 0xd0, 0x4d, 0x9d, 0xd6, 0xa6, 0x39, 0x4f, 0x6d, - 0x34, 0x6c, 0x2c, 0x21, 0x49, 0x3f, 0x92, 0x5a, 0xa9, 0xbf, 0x99, 0x06, 0x0b, 0xa9, 0xdd, 0x00, - 0xde, 0x01, 0xcb, 0xda, 0xc0, 0x75, 0x89, 0x45, 0xb7, 0x06, 0xe6, 0x1e, 0x71, 0xbb, 0xda, 0x3e, - 0xe9, 0x0d, 0x0c, 0xd2, 0xe3, 0x2b, 0x5a, 0x6e, 0xd7, 0x85, 0xaf, 0xcb, 0x1d, 0x29, 0x0a, 0xe5, - 0x58, 0xc3, 0x1f, 0x01, 0x68, 0xf1, 0xa6, 0x4d, 0xdd, 0xf3, 0x42, 0xce, 0x02, 0xe7, 0x0c, 0x13, - 0x70, 0x2b, 0x83, 0x40, 0x12, 0x2b, 0xe6, 0x63, 0x8f, 0x78, 0xba, 0x4b, 0x7a, 0x69, 0x1f, 0x8b, - 0x49, 0x1f, 0xd7, 0xa5, 0x28, 0x94, 0x63, 0x0d, 0x5f, 0x06, 0x55, 0xff, 0x6d, 0x7c, 0xce, 0xc5, - 0xe2, 0x2c, 0x0a, 0xb2, 0xea, 0x56, 0xd4, 0x85, 0xe2, 0x38, 0x36, 0x34, 0x7b, 0xcf, 0x23, 0xee, - 0x01, 0xe9, 0xbd, 0xe5, 0x6b, 0x00, 0x56, 0x28, 0xcb, 0xbc, 0x50, 0x86, 0x43, 0xdb, 0xce, 0x20, - 0x90, 0xc4, 0x8a, 0x0d, 0xcd, 0x8f, 0x9a, 0xcc, 0xd0, 0xa6, 0x93, 0x43, 0xdb, 0x95, 0xa2, 0x50, - 0x8e, 0x35, 0x8b, 0x3d, 0xdf, 0xe5, 0xb5, 0x03, 0xac, 0x1b, 0x78, 0xcf, 0x20, 0xb5, 0x99, 0x64, - 0xec, 0x6d, 0x25, 0xbb, 0x51, 0x1a, 0x0f, 0xdf, 0x02, 0xe7, 0xfc, 0xa6, 0x5d, 0x0b, 0x87, 0x24, - 0x15, 0x4e, 0xf2, 0x8c, 0x20, 0x39, 0xb7, 0x95, 0x06, 0xa0, 0xac, 0x0d, 0xbc, 0x05, 0xe6, 0x35, - 0xdb, 0x30, 0x78, 0x3c, 0x76, 0xec, 0x81, 0x45, 0x6b, 0xb3, 0x9c, 0x05, 0xb2, 0x1c, 0xea, 0x24, - 0x7a, 0x50, 0x0a, 0x09, 0xef, 0x02, 0xa0, 0x05, 0xe5, 0xc0, 0xab, 0x81, 0xfc, 0x42, 0x9f, 0xad, - 0x43, 0x51, 0x01, 0x0e, 0x9b, 0x3c, 0x14, 0x63, 0x53, 0x3f, 0x56, 0xc0, 0x4a, 0x4e, 0x8e, 0xc3, - 0x37, 0x12, 0x55, 0xef, 0x6a, 0xaa, 0xea, 0x5d, 0xc8, 0x31, 0x8b, 0x95, 0x3e, 0x0d, 0xcc, 0x31, - 0xdd, 0xa1, 0x5b, 0x7d, 0x1f, 0x22, 0x76, 0xb0, 0x17, 0x64, 0xbe, 0xa3, 0x38, 0x30, 0xda, 0x86, - 0xcf, 0x8d, 0x86, 0x8d, 0xb9, 0x44, 0x1f, 0x4a, 0x72, 0xaa, 0xbf, 0x2a, 0x00, 0xb0, 0x4e, 0x1c, - 0xc3, 0x3e, 0x34, 0x89, 0x75, 0x1a, 0xaa, 0x65, 0x3d, 0xa1, 0x5a, 0x54, 0xe9, 0x42, 0x84, 0xfe, - 0xe4, 0xca, 0x96, 0x8d, 0x94, 0x6c, 0xb9, 0x34, 0x86, 0xe7, 0x68, 0xdd, 0xf2, 0xb7, 0x22, 0x58, - 0x8c, 0xc0, 0x91, 0x70, 0x79, 0x2d, 0xb1, 0x84, 0x57, 0x52, 0x4b, 0xb8, 0x22, 0x31, 0x79, 0x6a, - 0xca, 0xe5, 0x7d, 0x30, 0xcf, 0x74, 0x85, 0xbf, 0x6a, 0x5c, 0xb5, 0x4c, 0x1f, 0x5b, 0xb5, 0x84, - 0x55, 0x67, 0x23, 0xc1, 0x84, 0x52, 0xcc, 0x39, 0x2a, 0x69, 0xe6, 0xab, 0xa8, 0x92, 0xfe, 0xa8, - 0x80, 0xf9, 0x68, 0x99, 0x4e, 0x41, 0x26, 0x75, 0x92, 0x32, 0xa9, 0x7e, 0x74, 0x5c, 0xe6, 0xe8, - 0xa4, 0xbf, 0x96, 0xe2, 0x5e, 0x73, 0xa1, 0xb4, 0xca, 0x0e, 0x54, 0x8e, 0xa1, 0x6b, 0xd8, 0x13, - 0x65, 0xf5, 0x8c, 0x7f, 0x98, 0xf2, 0xdb, 0x50, 0xd8, 0x9b, 0x90, 0x54, 0x85, 0xa7, 0x2b, 0xa9, - 0x8a, 0x5f, 0x8c, 0xa4, 0xba, 0x0d, 0x2a, 0x5e, 0x20, 0xa6, 0x4a, 0x9c, 0xf2, 0xf2, 0xb8, 0x74, - 0x16, 0x3a, 0x2a, 0x64, 0x0d, 0x15, 0x54, 0xc8, 0x24, 0xd3, 0x4e, 0xe5, 0x2f, 0x53, 0x3b, 0xb1, - 0xf0, 0x76, 0xf0, 0xc0, 0x23, 0x3d, 0x9e, 0x4a, 0x95, 0x28, 0xbc, 0x77, 0x78, 0x2b, 0x12, 0xbd, - 0x70, 0x17, 0xac, 0x38, 0xae, 0xdd, 0x77, 0x89, 0xe7, 0xad, 0x13, 0xdc, 0x33, 0x74, 0x8b, 0x04, - 0x03, 0xf0, 0xab, 0xde, 0x85, 0xd1, 0xb0, 0xb1, 0xb2, 0x23, 0x87, 0xa0, 0x3c, 0x5b, 0xf5, 0xa3, - 0x12, 0x38, 0x9b, 0xde, 0x11, 0x73, 0x84, 0x88, 0x72, 0x22, 0x21, 0xf2, 0x62, 0x2c, 0x44, 0x7d, - 0x95, 0x16, 0x3b, 0xf3, 0x67, 0xc2, 0x74, 0x0d, 0x2c, 0x08, 0xe1, 0x11, 0x74, 0x0a, 0x29, 0x16, - 0x2e, 0xcf, 0x6e, 0xb2, 0x1b, 0xa5, 0xf1, 0xf0, 0x35, 0x30, 0xe7, 0x72, 0x6d, 0x15, 0x10, 0xf8, - 0xfa, 0xe4, 0x5b, 0x82, 0x60, 0x0e, 0xc5, 0x3b, 0x51, 0x12, 0xcb, 0xb4, 0x49, 0x24, 0x39, 0x02, - 0x82, 0x52, 0x52, 0x9b, 0xac, 0xa5, 0x01, 0x28, 0x6b, 0x03, 0x37, 0xc1, 0xe2, 0xc0, 0xca, 0x52, - 0xf9, 0xb1, 0x76, 0x41, 0x50, 0x2d, 0xee, 0x66, 0x21, 0x48, 0x66, 0x07, 0x7f, 0x92, 0x90, 0x2b, - 0xd3, 0x7c, 0x17, 0xb9, 0x72, 0x74, 0x3a, 0x4c, 0xac, 0x57, 0x24, 0x3a, 0xaa, 0x32, 0xa9, 0x8e, - 0x52, 0x3f, 0x54, 0x00, 0xcc, 0xa6, 0xe0, 0xd8, 0xc3, 0x7d, 0xc6, 0x22, 0x56, 0x22, 0x7b, 0x72, - 0x85, 0x73, 0x75, 0xbc, 0xc2, 0x89, 0x76, 0xd0, 0xc9, 0x24, 0x8e, 0x98, 0xde, 0xd3, 0xb9, 0x98, - 0x99, 0x40, 0xe2, 0x44, 0xfe, 0x3c, 0x99, 0xc4, 0x89, 0xf1, 0x1c, 0x2d, 0x71, 0xfe, 0x59, 0x00, - 0x8b, 0x11, 0x78, 0x62, 0x89, 0x23, 0x31, 0xf9, 0xe6, 0x72, 0x66, 0x32, 0xd9, 0x11, 0x4d, 0xdd, - 0xff, 0x89, 0xec, 0x88, 0x1c, 0xca, 0x91, 0x1d, 0xbf, 0x2f, 0xc4, 0xbd, 0x3e, 0xa6, 0xec, 0xf8, - 0x02, 0xae, 0x2a, 0xbe, 0x72, 0xca, 0x45, 0xfd, 0xa4, 0x08, 0xce, 0xa6, 0x53, 0x30, 0x51, 0x07, - 0x95, 0xb1, 0x75, 0x70, 0x07, 0x2c, 0xdd, 0x1b, 0x18, 0xc6, 0x21, 0x1f, 0x43, 0xac, 0x18, 0xfa, - 0x15, 0xf4, 0xdb, 0xc2, 0x72, 0xe9, 0x07, 0x12, 0x0c, 0x92, 0x5a, 0x66, 0xcb, 0x62, 0xe9, 0x49, - 0xcb, 0x62, 0xf9, 0x04, 0x65, 0x51, 0xae, 0x2c, 0x8a, 0x27, 0x52, 0x16, 0x13, 0xd7, 0x44, 0xc9, - 0x76, 0x35, 0xf6, 0x0c, 0x3f, 0x52, 0xc0, 0xb2, 0xfc, 0xf8, 0x0c, 0x0d, 0x30, 0x6f, 0xe2, 0x07, - 0xf1, 0xcb, 0x8b, 0x71, 0x05, 0x63, 0x40, 0x75, 0xa3, 0xe9, 0x7f, 0xdd, 0x69, 0xbe, 0x6d, 0xd1, - 0x6d, 0xb7, 0x4b, 0x5d, 0xdd, 0xea, 0xfb, 0x05, 0x76, 0x33, 0xc1, 0x85, 0x52, 0xdc, 0xf0, 0x2e, - 0xa8, 0x98, 0xf8, 0x41, 0x77, 0xe0, 0xf6, 0x83, 0x42, 0x78, 0xfc, 0xf7, 0xf0, 0xd8, 0xdf, 0x14, - 0x2c, 0x28, 0xe4, 0x53, 0x3f, 0x57, 0xc0, 0x4a, 0x4e, 0x05, 0xfd, 0x1a, 0x8d, 0xf2, 0x23, 0x05, - 0x5c, 0x4c, 0x8c, 0x92, 0x65, 0x24, 0xb9, 0x37, 0x30, 0x78, 0x72, 0x0a, 0xc1, 0x72, 0x15, 0xcc, - 0x3a, 0xd8, 0xa5, 0x7a, 0xa8, 0x74, 0xcb, 0xed, 0xb9, 0xd1, 0xb0, 0x31, 0xbb, 0x13, 0x34, 0xa2, - 0xa8, 0x5f, 0x32, 0x37, 0x85, 0xa7, 0x37, 0x37, 0xea, 0xaf, 0x0b, 0xa0, 0x1a, 0x73, 0xf9, 0x14, - 0xa4, 0xca, 0x9b, 0x09, 0xa9, 0x22, 0xfd, 0xf8, 0x13, 0x9f, 0xc3, 0x3c, 0xad, 0xb2, 0x99, 0xd2, - 0x2a, 0xdf, 0x1d, 0x47, 0x74, 0xb4, 0x58, 0xf9, 0x57, 0x01, 0x2c, 0xc5, 0xd0, 0x91, 0x5a, 0xf9, - 0x7e, 0x42, 0xad, 0xac, 0xa6, 0xd4, 0x4a, 0x4d, 0x66, 0xf3, 0x8d, 0x5c, 0x19, 0x2f, 0x57, 0xfe, - 0xa4, 0x80, 0x85, 0xd8, 0xdc, 0x9d, 0x82, 0x5e, 0x59, 0x4f, 0xea, 0x95, 0xc6, 0x98, 0x78, 0xc9, - 0x11, 0x2c, 0xb7, 0xc0, 0x62, 0x0c, 0xb4, 0xed, 0xf6, 0x74, 0x0b, 0x1b, 0x1e, 0x7c, 0x0e, 0x94, - 0x3d, 0x8a, 0x5d, 0x1a, 0x64, 0x77, 0x60, 0xdb, 0x65, 0x8d, 0xc8, 0xef, 0x53, 0xff, 0xad, 0x80, - 0x56, 0xcc, 0x78, 0x87, 0xb8, 0x9e, 0xee, 0x51, 0x62, 0xd1, 0x3b, 0xb6, 0x31, 0x30, 0x49, 0xc7, - 0xc0, 0xba, 0x89, 0x08, 0x6b, 0xd0, 0x6d, 0x6b, 0xc7, 0x36, 0x74, 0xed, 0x10, 0x62, 0x50, 0xfd, - 0x60, 0x9f, 0x58, 0xeb, 0xc4, 0x20, 0x54, 0x7c, 0xde, 0x98, 0x6d, 0xbf, 0x11, 0xdc, 0xf6, 0xbf, - 0x1b, 0x75, 0x3d, 0x1e, 0x36, 0x56, 0x27, 0x61, 0xe4, 0xc1, 0x19, 0xe7, 0x84, 0x3f, 0x03, 0x80, - 0x3d, 0x76, 0x35, 0x1c, 0x7c, 0xec, 0x98, 0x6d, 0xbf, 0x1e, 0xa4, 0xf0, 0xbb, 0x61, 0xcf, 0xb1, - 0x5e, 0x10, 0x63, 0x54, 0x7f, 0x57, 0x49, 0x2c, 0xf5, 0xd7, 0xfe, 0x6e, 0xe9, 0x17, 0x60, 0xe9, - 0x20, 0x9a, 0x9d, 0x00, 0xc0, 0x34, 0x11, 0x8b, 0xbb, 0xe7, 0xa5, 0xf4, 0xb2, 0x79, 0x8d, 0x94, - 0xd8, 0x1d, 0x09, 0x1d, 0x92, 0xbe, 0x04, 0xbe, 0x0c, 0xaa, 0x4c, 0xcb, 0xe8, 0x1a, 0xd9, 0xc2, - 0x66, 0x90, 0x86, 0xe1, 0xd7, 0xa1, 0x6e, 0xd4, 0x85, 0xe2, 0x38, 0xb8, 0x0f, 0x16, 0x1d, 0xbb, - 0xb7, 0x89, 0x2d, 0xdc, 0x27, 0xac, 0x42, 0xfb, 0x4b, 0xc9, 0x6f, 0x9d, 0x66, 0xdb, 0xaf, 0x04, - 0x37, 0x0a, 0x3b, 0x59, 0x08, 0x3b, 0xb1, 0x49, 0x9a, 0x79, 0x10, 0xc8, 0x28, 0xa1, 0x99, 0xf9, - 0x98, 0x39, 0x93, 0xf9, 0x07, 0x88, 0x2c, 0x1f, 0x4f, 0xf8, 0x39, 0x33, 0xef, 0x3e, 0xad, 0x72, - 0xa2, 0xfb, 0x34, 0xc9, 0x89, 0x63, 0xf6, 0x98, 0x27, 0x8e, 0x4f, 0x14, 0x70, 0xc9, 0x99, 0x20, - 0x8d, 0x6a, 0x80, 0x4f, 0x4b, 0x67, 0xcc, 0xb4, 0x4c, 0x92, 0x91, 0xed, 0xd5, 0xd1, 0xb0, 0x71, - 0x69, 0x12, 0x24, 0x9a, 0xc8, 0x35, 0x96, 0x34, 0xb6, 0xd8, 0xf9, 0x6a, 0x55, 0xee, 0xe6, 0x95, - 0x31, 0x6e, 0x06, 0x1b, 0xa5, 0x9f, 0x87, 0xc1, 0x13, 0x0a, 0x69, 0xd4, 0x0f, 0xcb, 0xe0, 0x5c, - 0xa6, 0x5a, 0x7f, 0x89, 0x77, 0x85, 0x99, 0x13, 0x4d, 0xf1, 0x18, 0x27, 0x9a, 0x35, 0xb0, 0x20, - 0x3e, 0x30, 0xa7, 0x0e, 0x44, 0x61, 0x98, 0x74, 0x92, 0xdd, 0x28, 0x8d, 0x97, 0xdd, 0x55, 0x96, - 0x8f, 0x79, 0x57, 0x19, 0xf7, 0x42, 0xfc, 0x2f, 0xca, 0xcf, 0xe7, 0xac, 0x17, 0xe2, 0xef, 0x51, - 0x69, 0x3c, 0x7c, 0x3d, 0x48, 0xd6, 0x90, 0x61, 0x86, 0x33, 0xa4, 0xb2, 0x2f, 0x24, 0x48, 0xa1, - 0x9f, 0xe8, 0x23, 0xea, 0x7b, 0x92, 0x8f, 0xa8, 0xab, 0x63, 0xc2, 0x6c, 0xf2, 0x6b, 0x49, 0xe9, - 0xa1, 0xb3, 0x7a, 0xfc, 0x43, 0xa7, 0xfa, 0x17, 0x05, 0x3c, 0x93, 0xbb, 0x4d, 0xc1, 0xb5, 0x84, - 0x7a, 0xbc, 0x96, 0x52, 0x8f, 0xcf, 0xe6, 0x1a, 0xc6, 0x24, 0xa4, 0x29, 0xbf, 0xb1, 0xbc, 0x39, - 0xf6, 0xc6, 0x52, 0x72, 0x12, 0x19, 0x7f, 0x75, 0xd9, 0x7e, 0xf5, 0xe1, 0xa3, 0xfa, 0xd4, 0xa7, - 0x8f, 0xea, 0x53, 0x9f, 0x3d, 0xaa, 0x4f, 0xfd, 0x72, 0x54, 0x57, 0x1e, 0x8e, 0xea, 0xca, 0xa7, - 0xa3, 0xba, 0xf2, 0xd9, 0xa8, 0xae, 0xfc, 0x7d, 0x54, 0x57, 0x7e, 0xfb, 0x79, 0x7d, 0xea, 0x2e, - 0xcc, 0xfe, 0x2b, 0xf3, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xd3, 0xfa, 0xed, 0x70, 0xaa, 0x29, - 0x00, 0x00, + 0x15, 0xd7, 0x52, 0xa4, 0x44, 0x0d, 0x2d, 0xc9, 0x1e, 0xa9, 0x12, 0x63, 0x37, 0xa4, 0xbb, 0x71, + 0x6d, 0x25, 0x8e, 0xc9, 0xda, 0x71, 0x82, 0xc0, 0x29, 0x12, 0x88, 0x54, 0x9a, 0xba, 0xd1, 0x57, + 0x87, 0x92, 0x03, 0xb8, 0x69, 0xd1, 0xd1, 0x72, 0x4c, 0x6d, 0xbc, 0x5f, 0xd8, 0x1d, 0x2a, 0x16, + 0x7a, 0x29, 0x0a, 0x14, 0xe8, 0x21, 0x87, 0xfe, 0x0d, 0xfd, 0x07, 0x8a, 0xa2, 0x68, 0x6e, 0x45, + 0x50, 0xf4, 0xe2, 0x4b, 0x81, 0xa0, 0x97, 0xe6, 0x44, 0xd4, 0xcc, 0xa9, 0x28, 0x7a, 0x6b, 0x2f, + 0xbe, 0xb4, 0x98, 0xd9, 0xd9, 0xef, 0x59, 0x91, 0x92, 0x63, 0xa5, 0x09, 0x7c, 0xe3, 0xce, 0x7b, + 0xef, 0x37, 0x6f, 0x66, 0xde, 0x9b, 0xf7, 0x9b, 0x19, 0x02, 0xf5, 0xfe, 0xeb, 0x5e, 0x43, 0xb7, + 0x9b, 0xd8, 0xd1, 0x9b, 0xd8, 0x71, 0xbc, 0xe6, 0xc1, 0xf5, 0x66, 0x8f, 0x58, 0xc4, 0xc5, 0x94, + 0x74, 0x1b, 0x8e, 0x6b, 0x53, 0x1b, 0x42, 0x5f, 0xa7, 0x81, 0x1d, 0xbd, 0xc1, 0x74, 0x1a, 0x07, + 0xd7, 0xcf, 0x5f, 0xeb, 0xe9, 0x74, 0xbf, 0xbf, 0xd7, 0xd0, 0x6c, 0xb3, 0xd9, 0xb3, 0x7b, 0x76, + 0x93, 0xab, 0xee, 0xf5, 0xef, 0xf1, 0x2f, 0xfe, 0xc1, 0x7f, 0xf9, 0x10, 0xe7, 0xe3, 0xdd, 0x68, + 0xb6, 0x4b, 0x24, 0xdd, 0x9c, 0xbf, 0x19, 0xe9, 0x98, 0x58, 0xdb, 0xd7, 0x2d, 0xe2, 0x1e, 0x36, + 0x9d, 0xfb, 0x3d, 0xd6, 0xe0, 0x35, 0x4d, 0x42, 0xb1, 0xcc, 0xaa, 0x99, 0x67, 0xe5, 0xf6, 0x2d, + 0xaa, 0x9b, 0x24, 0x63, 0xf0, 0xda, 0x28, 0x03, 0x4f, 0xdb, 0x27, 0x26, 0xce, 0xd8, 0xbd, 0x92, + 0x67, 0xd7, 0xa7, 0xba, 0xd1, 0xd4, 0x2d, 0xea, 0x51, 0x37, 0x6d, 0xa4, 0xfe, 0x47, 0x01, 0xb0, + 0x6d, 0x5b, 0xd4, 0xb5, 0x0d, 0x83, 0xb8, 0x88, 0x1c, 0xe8, 0x9e, 0x6e, 0x5b, 0xf0, 0xa7, 0xa0, + 0xcc, 0xc6, 0xd3, 0xc5, 0x14, 0x57, 0x95, 0x8b, 0xca, 0x4a, 0xe5, 0xc6, 0x77, 0x1a, 0xd1, 0x24, + 0x87, 0xf0, 0x0d, 0xe7, 0x7e, 0x8f, 0x35, 0x78, 0x0d, 0xa6, 0xdd, 0x38, 0xb8, 0xde, 0xd8, 0xda, + 0xfb, 0x80, 0x68, 0x74, 0x83, 0x50, 0xdc, 0x82, 0x0f, 0x07, 0xf5, 0x89, 0xe1, 0xa0, 0x0e, 0xa2, + 0x36, 0x14, 0xa2, 0xc2, 0x2d, 0x50, 0xe4, 0xe8, 0x05, 0x8e, 0x7e, 0x2d, 0x17, 0x5d, 0x0c, 0xba, + 0x81, 0xf0, 0x87, 0x6f, 0x3f, 0xa0, 0xc4, 0x62, 0xee, 0xb5, 0xce, 0x08, 0xe8, 0xe2, 0x1a, 0xa6, + 0x18, 0x71, 0x20, 0xf8, 0x32, 0x28, 0xbb, 0xc2, 0xfd, 0xea, 0xe4, 0x45, 0x65, 0x65, 0xb2, 0x75, + 0x56, 0x68, 0x95, 0x83, 0x61, 0xa1, 0x50, 0x43, 0xfd, 0xb3, 0x02, 0x96, 0xb2, 0xe3, 0x5e, 0xd7, + 0x3d, 0x0a, 0xdf, 0xcf, 0x8c, 0xbd, 0x31, 0xde, 0xd8, 0x99, 0x35, 0x1f, 0x79, 0xd8, 0x71, 0xd0, + 0x12, 0x1b, 0xf7, 0xbb, 0xa0, 0xa4, 0x53, 0x62, 0x7a, 0xd5, 0xc2, 0xc5, 0xc9, 0x95, 0xca, 0x8d, + 0xcb, 0x8d, 0x6c, 0xec, 0x36, 0xb2, 0x8e, 0xb5, 0x66, 0x05, 0x64, 0xe9, 0x36, 0x33, 0x46, 0x3e, + 0x86, 0xfa, 0x5f, 0x05, 0xcc, 0xac, 0x61, 0x62, 0xda, 0x56, 0x87, 0xd0, 0x53, 0x58, 0xb4, 0x36, + 0x28, 0x7a, 0x0e, 0xd1, 0xc4, 0xa2, 0x7d, 0x4b, 0xe6, 0x7b, 0xe8, 0x4e, 0xc7, 0x21, 0x5a, 0xb4, + 0x50, 0xec, 0x0b, 0x71, 0x63, 0xf8, 0x2e, 0x98, 0xf2, 0x28, 0xa6, 0x7d, 0x8f, 0x2f, 0x53, 0xe5, + 0xc6, 0x0b, 0x47, 0xc3, 0x70, 0xd5, 0xd6, 0x9c, 0x00, 0x9a, 0xf2, 0xbf, 0x91, 0x80, 0x50, 0xff, + 0x51, 0x00, 0x30, 0xd4, 0x6d, 0xdb, 0x56, 0x57, 0xa7, 0x2c, 0x7e, 0x6f, 0x81, 0x22, 0x3d, 0x74, + 0x08, 0x9f, 0x86, 0x99, 0xd6, 0xe5, 0xc0, 0x8b, 0x9d, 0x43, 0x87, 0x3c, 0x1e, 0xd4, 0x97, 0xb2, + 0x16, 0x4c, 0x82, 0xb8, 0x0d, 0x5c, 0x0f, 0xfd, 0x2b, 0x70, 0xeb, 0x9b, 0xc9, 0xae, 0x1f, 0x0f, + 0xea, 0x92, 0xcd, 0xa2, 0x11, 0x22, 0x25, 0x1d, 0x84, 0x07, 0x00, 0x1a, 0xd8, 0xa3, 0x3b, 0x2e, + 0xb6, 0x3c, 0xbf, 0x27, 0xdd, 0x24, 0x62, 0xe4, 0x2f, 0x8d, 0xb7, 0x3c, 0xcc, 0xa2, 0x75, 0x5e, + 0x78, 0x01, 0xd7, 0x33, 0x68, 0x48, 0xd2, 0x03, 0xbc, 0x0c, 0xa6, 0x5c, 0x82, 0x3d, 0xdb, 0xaa, + 0x16, 0xf9, 0x28, 0xc2, 0x09, 0x44, 0xbc, 0x15, 0x09, 0x29, 0x7c, 0x11, 0x4c, 0x9b, 0xc4, 0xf3, + 0x70, 0x8f, 0x54, 0x4b, 0x5c, 0x71, 0x5e, 0x28, 0x4e, 0x6f, 0xf8, 0xcd, 0x28, 0x90, 0xab, 0xbf, + 0x53, 0xc0, 0x6c, 0x38, 0x73, 0xa7, 0x90, 0x2a, 0xad, 0x64, 0xaa, 0x3c, 0x7f, 0x64, 0x9c, 0xe4, + 0x64, 0xc8, 0x27, 0x93, 0x31, 0x9f, 0x59, 0x10, 0xc2, 0x1f, 0x83, 0xb2, 0x47, 0x0c, 0xa2, 0x51, + 0xdb, 0x15, 0x3e, 0xbf, 0x32, 0xa6, 0xcf, 0x78, 0x8f, 0x18, 0x1d, 0x61, 0xda, 0x3a, 0xc3, 0x9c, + 0x0e, 0xbe, 0x50, 0x08, 0x09, 0x7f, 0x08, 0xca, 0x94, 0x98, 0x8e, 0x81, 0x29, 0x11, 0x69, 0x92, + 0x88, 0x6f, 0x16, 0x2e, 0x0c, 0x6c, 0xdb, 0xee, 0xee, 0x08, 0x35, 0x9e, 0x28, 0xe1, 0x3c, 0x04, + 0xad, 0x28, 0x84, 0x81, 0xf7, 0xc1, 0x5c, 0xdf, 0xe9, 0x32, 0x4d, 0xca, 0xb6, 0xee, 0xde, 0xa1, + 0x08, 0x9f, 0xab, 0x47, 0x4e, 0xc8, 0x6e, 0xc2, 0xa4, 0xb5, 0x24, 0x3a, 0x98, 0x4b, 0xb6, 0xa3, + 0x14, 0x34, 0x5c, 0x05, 0xf3, 0xa6, 0x6e, 0x21, 0x82, 0xbb, 0x87, 0x1d, 0xa2, 0xd9, 0x56, 0xd7, + 0xe3, 0x01, 0x54, 0x6a, 0x2d, 0x0b, 0x80, 0xf9, 0x8d, 0xa4, 0x18, 0xa5, 0xf5, 0xe1, 0x3a, 0x58, + 0x0c, 0xf6, 0xd9, 0xef, 0xeb, 0x1e, 0xb5, 0xdd, 0xc3, 0x75, 0xdd, 0xd4, 0x69, 0x75, 0x8a, 0xe3, + 0x54, 0x87, 0x83, 0xfa, 0x22, 0x92, 0xc8, 0x91, 0xd4, 0x4a, 0xfd, 0x68, 0x0a, 0xcc, 0xa7, 0x76, + 0x03, 0x78, 0x07, 0x2c, 0x69, 0x7d, 0xd7, 0x25, 0x16, 0xdd, 0xec, 0x9b, 0x7b, 0xc4, 0xed, 0x68, + 0xfb, 0xa4, 0xdb, 0x37, 0x48, 0x97, 0xaf, 0x68, 0xa9, 0x55, 0x13, 0xbe, 0x2e, 0xb5, 0xa5, 0x5a, + 0x28, 0xc7, 0x1a, 0xfe, 0x00, 0x40, 0x8b, 0x37, 0x6d, 0xe8, 0x9e, 0x17, 0x62, 0x16, 0x38, 0x66, + 0x98, 0x80, 0x9b, 0x19, 0x0d, 0x24, 0xb1, 0x62, 0x3e, 0x76, 0x89, 0xa7, 0xbb, 0xa4, 0x9b, 0xf6, + 0x71, 0x32, 0xe9, 0xe3, 0x9a, 0x54, 0x0b, 0xe5, 0x58, 0xc3, 0x57, 0x41, 0xc5, 0xef, 0x8d, 0xcf, + 0xb9, 0x58, 0x9c, 0x05, 0x01, 0x56, 0xd9, 0x8c, 0x44, 0x28, 0xae, 0xc7, 0x86, 0x66, 0xef, 0x79, + 0xc4, 0x3d, 0x20, 0xdd, 0x77, 0x7c, 0x0e, 0xc0, 0x0a, 0x65, 0x89, 0x17, 0xca, 0x70, 0x68, 0x5b, + 0x19, 0x0d, 0x24, 0xb1, 0x62, 0x43, 0xf3, 0xa3, 0x26, 0x33, 0xb4, 0xa9, 0xe4, 0xd0, 0x76, 0xa5, + 0x5a, 0x28, 0xc7, 0x9a, 0xc5, 0x9e, 0xef, 0xf2, 0xea, 0x01, 0xd6, 0x0d, 0xbc, 0x67, 0x90, 0xea, + 0x74, 0x32, 0xf6, 0x36, 0x93, 0x62, 0x94, 0xd6, 0x87, 0xef, 0x80, 0x73, 0x7e, 0xd3, 0xae, 0x85, + 0x43, 0x90, 0x32, 0x07, 0x79, 0x4e, 0x80, 0x9c, 0xdb, 0x4c, 0x2b, 0xa0, 0xac, 0x0d, 0xbc, 0x05, + 0xe6, 0x34, 0xdb, 0x30, 0x78, 0x3c, 0xb6, 0xed, 0xbe, 0x45, 0xab, 0x33, 0x1c, 0x05, 0xb2, 0x1c, + 0x6a, 0x27, 0x24, 0x28, 0xa5, 0x09, 0xef, 0x02, 0xa0, 0x05, 0xe5, 0xc0, 0xab, 0x82, 0xfc, 0x42, + 0x9f, 0xad, 0x43, 0x51, 0x01, 0x0e, 0x9b, 0x3c, 0x14, 0x43, 0x53, 0x3f, 0x51, 0xc0, 0x72, 0x4e, + 0x8e, 0xc3, 0xb7, 0x12, 0x55, 0xef, 0x6a, 0xaa, 0xea, 0x5d, 0xc8, 0x31, 0x8b, 0x95, 0x3e, 0x0d, + 0xcc, 0x32, 0xde, 0xa1, 0x5b, 0x3d, 0x5f, 0x45, 0xec, 0x60, 0x2f, 0xc9, 0x7c, 0x47, 0x71, 0xc5, + 0x68, 0x1b, 0x3e, 0x37, 0x1c, 0xd4, 0x67, 0x13, 0x32, 0x94, 0xc4, 0x54, 0x7f, 0x51, 0x00, 0x60, + 0x8d, 0x38, 0x86, 0x7d, 0x68, 0x12, 0xeb, 0x34, 0x58, 0xcb, 0x5a, 0x82, 0xb5, 0xa8, 0xd2, 0x85, + 0x08, 0xfd, 0xc9, 0xa5, 0x2d, 0xeb, 0x29, 0xda, 0x72, 0x69, 0x04, 0xce, 0xd1, 0xbc, 0xe5, 0x6f, + 0x93, 0x60, 0x21, 0x52, 0x8e, 0x88, 0xcb, 0x1b, 0x89, 0x25, 0xbc, 0x92, 0x5a, 0xc2, 0x65, 0x89, + 0xc9, 0x53, 0x63, 0x2e, 0x1f, 0x80, 0x39, 0xc6, 0x2b, 0xfc, 0x55, 0xe3, 0xac, 0x65, 0xea, 0xd8, + 0xac, 0x25, 0xac, 0x3a, 0xeb, 0x09, 0x24, 0x94, 0x42, 0xce, 0x61, 0x49, 0xd3, 0x5f, 0x45, 0x96, + 0xf4, 0x7b, 0x05, 0xcc, 0x45, 0xcb, 0x74, 0x0a, 0x34, 0xa9, 0x9d, 0xa4, 0x49, 0xb5, 0xa3, 0xe3, + 0x32, 0x87, 0x27, 0xfd, 0xb5, 0x18, 0xf7, 0x9a, 0x13, 0xa5, 0x15, 0x76, 0xa0, 0x72, 0x0c, 0x5d, + 0xc3, 0x9e, 0x28, 0xab, 0x67, 0xfc, 0xc3, 0x94, 0xdf, 0x86, 0x42, 0x69, 0x82, 0x52, 0x15, 0x9e, + 0x2e, 0xa5, 0x9a, 0xfc, 0x62, 0x28, 0xd5, 0x0e, 0x28, 0x7b, 0x01, 0x99, 0x2a, 0x72, 0xc8, 0xcb, + 0xa3, 0xd2, 0x59, 0xf0, 0xa8, 0x10, 0x35, 0x64, 0x50, 0x21, 0x92, 0x8c, 0x3b, 0x95, 0xbe, 0x4c, + 0xee, 0xc4, 0xc2, 0xdb, 0xc1, 0x7d, 0x8f, 0x74, 0x79, 0x2a, 0x95, 0xa3, 0xf0, 0xde, 0xe6, 0xad, + 0x48, 0x48, 0xe1, 0x2e, 0x58, 0x76, 0x5c, 0xbb, 0xe7, 0x12, 0xcf, 0x5b, 0x23, 0xb8, 0x6b, 0xe8, + 0x16, 0x09, 0x06, 0xe0, 0x57, 0xbd, 0x0b, 0xc3, 0x41, 0x7d, 0x79, 0x5b, 0xae, 0x82, 0xf2, 0x6c, + 0xd5, 0x5f, 0x95, 0xc0, 0xd9, 0xf4, 0x8e, 0x98, 0x43, 0x44, 0x94, 0x13, 0x11, 0x91, 0x97, 0x63, + 0x21, 0xea, 0xb3, 0xb4, 0xd8, 0x99, 0x3f, 0x13, 0xa6, 0xab, 0x60, 0x5e, 0x10, 0x8f, 0x40, 0x28, + 0xa8, 0x58, 0xb8, 0x3c, 0xbb, 0x49, 0x31, 0x4a, 0xeb, 0xc3, 0x37, 0xc0, 0xac, 0xcb, 0xb9, 0x55, + 0x00, 0xe0, 0xf3, 0x93, 0x6f, 0x08, 0x80, 0x59, 0x14, 0x17, 0xa2, 0xa4, 0x2e, 0xe3, 0x26, 0x11, + 0xe5, 0x08, 0x00, 0x8a, 0x49, 0x6e, 0xb2, 0x9a, 0x56, 0x40, 0x59, 0x1b, 0xb8, 0x01, 0x16, 0xfa, + 0x56, 0x16, 0xca, 0x8f, 0xb5, 0x0b, 0x02, 0x6a, 0x61, 0x37, 0xab, 0x82, 0x64, 0x76, 0xf0, 0x36, + 0x58, 0xa0, 0xc4, 0x35, 0x75, 0x0b, 0x53, 0xdd, 0xea, 0x85, 0x70, 0xfe, 0xca, 0x2f, 0x33, 0xa8, + 0x9d, 0xac, 0x18, 0xc9, 0x6c, 0xe0, 0x8f, 0x12, 0xcc, 0x67, 0x8a, 0x6f, 0x48, 0x57, 0x8e, 0xce, + 0xac, 0xb1, 0xa9, 0x8f, 0x84, 0x92, 0x95, 0xc7, 0xa5, 0x64, 0xea, 0xc7, 0x0a, 0x80, 0xd9, 0x6c, + 0x1e, 0x79, 0x4f, 0x90, 0xb1, 0x88, 0x55, 0xdb, 0xae, 0x9c, 0x2c, 0x5d, 0x1d, 0x4d, 0x96, 0xa2, + 0xcd, 0x78, 0x3c, 0xb6, 0x24, 0xa6, 0xf7, 0x74, 0xee, 0x78, 0xc6, 0x60, 0x4b, 0x91, 0x3f, 0x4f, + 0xc6, 0x96, 0x62, 0x38, 0x47, 0xb3, 0xa5, 0x7f, 0x16, 0xc0, 0x42, 0xa4, 0x3c, 0x36, 0x5b, 0x92, + 0x98, 0x3c, 0xbb, 0xe7, 0x19, 0x8f, 0xc1, 0x44, 0x53, 0xf7, 0x7f, 0xc2, 0x60, 0x22, 0x87, 0x72, + 0x18, 0xcc, 0x6f, 0x0b, 0x71, 0xaf, 0x8f, 0xc9, 0x60, 0xbe, 0x80, 0x5b, 0x8f, 0xaf, 0x1c, 0x09, + 0x52, 0x3f, 0x2a, 0x82, 0xb3, 0xe9, 0x14, 0x4c, 0x94, 0x54, 0x65, 0x64, 0x49, 0xdd, 0x06, 0x8b, + 0xf7, 0xfa, 0x86, 0x71, 0xc8, 0xc7, 0x10, 0xab, 0xab, 0x7e, 0x31, 0xfe, 0xa6, 0xb0, 0x5c, 0xfc, + 0x9e, 0x44, 0x07, 0x49, 0x2d, 0xb3, 0x15, 0xb6, 0xf8, 0xa4, 0x15, 0xb6, 0x74, 0x82, 0x0a, 0x9b, + 0x53, 0x12, 0xa7, 0x4f, 0x50, 0x12, 0xe5, 0x7c, 0x67, 0xf2, 0x44, 0x7c, 0x67, 0xec, 0xf2, 0x2a, + 0xd9, 0xf9, 0x46, 0xde, 0x2c, 0x0c, 0x15, 0xb0, 0x24, 0x3f, 0xd4, 0x43, 0x03, 0xcc, 0x99, 0xf8, + 0x41, 0xfc, 0x4a, 0x65, 0x54, 0xed, 0xe9, 0x53, 0xdd, 0x68, 0xf8, 0x6f, 0x4e, 0x8d, 0xdb, 0x16, + 0xdd, 0x72, 0x3b, 0xd4, 0xd5, 0xad, 0x9e, 0x5f, 0xab, 0x37, 0x12, 0x58, 0x28, 0x85, 0x0d, 0xef, + 0x82, 0xb2, 0x89, 0x1f, 0x74, 0xfa, 0x6e, 0x2f, 0xa8, 0xa9, 0xc7, 0xef, 0x87, 0xa7, 0xd1, 0x86, + 0x40, 0x41, 0x21, 0x9e, 0xfa, 0xb9, 0x02, 0x96, 0x73, 0x8a, 0xf1, 0xd7, 0x68, 0x94, 0x7f, 0x54, + 0xc0, 0xc5, 0xc4, 0x28, 0x59, 0x72, 0x93, 0x7b, 0x7d, 0x83, 0xe7, 0xb9, 0xe0, 0x3e, 0x57, 0xc1, + 0x8c, 0x83, 0x5d, 0xaa, 0x87, 0xfc, 0xbb, 0xd4, 0x9a, 0x1d, 0x0e, 0xea, 0x33, 0xdb, 0x41, 0x23, + 0x8a, 0xe4, 0x92, 0xb9, 0x29, 0x3c, 0xbd, 0xb9, 0x51, 0x7f, 0x59, 0x00, 0x95, 0x98, 0xcb, 0xa7, + 0xc0, 0x7a, 0xde, 0x4e, 0xb0, 0x1e, 0xe9, 0x93, 0x54, 0x7c, 0x0e, 0xf3, 0x68, 0xcf, 0x46, 0x8a, + 0xf6, 0x7c, 0x7b, 0x14, 0xd0, 0xd1, 0xbc, 0xe7, 0x5f, 0x05, 0xb0, 0x18, 0xd3, 0x8e, 0x88, 0xcf, + 0x77, 0x13, 0xc4, 0x67, 0x25, 0x45, 0x7c, 0xaa, 0x32, 0x9b, 0x67, 0xcc, 0x67, 0x34, 0xf3, 0xf9, + 0x83, 0x02, 0xe6, 0x63, 0x73, 0x77, 0x0a, 0xd4, 0x67, 0x2d, 0x49, 0x7d, 0xea, 0x23, 0xe2, 0x25, + 0x87, 0xfb, 0xdc, 0x02, 0x0b, 0x31, 0xa5, 0x2d, 0xb7, 0xab, 0x5b, 0xd8, 0xf0, 0xe0, 0x0b, 0xa0, + 0xe4, 0x51, 0xec, 0xd2, 0x20, 0xbb, 0x03, 0xdb, 0x0e, 0x6b, 0x44, 0xbe, 0x4c, 0xfd, 0xb7, 0x02, + 0x9a, 0x31, 0xe3, 0x6d, 0xe2, 0x7a, 0xba, 0x47, 0x89, 0x45, 0xef, 0xd8, 0x46, 0xdf, 0x24, 0x6d, + 0x03, 0xeb, 0x26, 0x22, 0xac, 0x41, 0xb7, 0xad, 0x6d, 0xdb, 0xd0, 0xb5, 0x43, 0x88, 0x41, 0xe5, + 0xc3, 0x7d, 0x62, 0xad, 0x11, 0x83, 0x50, 0xf1, 0xe8, 0x32, 0xd3, 0x7a, 0x2b, 0x78, 0x83, 0x78, + 0x2f, 0x12, 0x3d, 0x1e, 0xd4, 0x57, 0xc6, 0x41, 0xe4, 0xc1, 0x19, 0xc7, 0x84, 0x3f, 0x01, 0x80, + 0x7d, 0x76, 0x34, 0x1c, 0x3c, 0xc1, 0xcc, 0xb4, 0xde, 0x0c, 0x52, 0xf8, 0xbd, 0x50, 0x72, 0xac, + 0x0e, 0x62, 0x88, 0xea, 0x6f, 0xca, 0x89, 0xa5, 0xfe, 0xda, 0xdf, 0x78, 0xfd, 0x0c, 0x2c, 0x1e, + 0x44, 0xb3, 0x13, 0x28, 0x30, 0x7a, 0xc5, 0xe2, 0xee, 0x45, 0x29, 0xbc, 0x6c, 0x5e, 0x23, 0x52, + 0x77, 0x47, 0x02, 0x87, 0xa4, 0x9d, 0xc0, 0x57, 0x41, 0x85, 0x71, 0x19, 0x5d, 0x23, 0x9b, 0xd8, + 0x0c, 0xd2, 0x30, 0x7c, 0xb3, 0xea, 0x44, 0x22, 0x14, 0xd7, 0x83, 0xfb, 0x60, 0xc1, 0xb1, 0xbb, + 0x1b, 0xd8, 0xc2, 0x3d, 0xc2, 0x2a, 0xb4, 0xbf, 0x94, 0xfc, 0x2e, 0x6c, 0xa6, 0xf5, 0x5a, 0x70, + 0xcf, 0xb1, 0x9d, 0x55, 0x61, 0x87, 0x3f, 0x49, 0x33, 0x0f, 0x02, 0x19, 0x24, 0x34, 0x33, 0x4f, + 0xac, 0xd3, 0x99, 0xff, 0xa5, 0xc8, 0xf2, 0xf1, 0x84, 0x8f, 0xac, 0x79, 0xb7, 0x7c, 0xe5, 0x13, + 0xdd, 0xf2, 0x49, 0x0e, 0x2f, 0x33, 0xc7, 0x3c, 0xbc, 0xfc, 0x49, 0x01, 0x97, 0x9c, 0x31, 0xd2, + 0xa8, 0x0a, 0xf8, 0xb4, 0xb4, 0x47, 0x4c, 0xcb, 0x38, 0x19, 0xd9, 0x5a, 0x19, 0x0e, 0xea, 0x97, + 0xc6, 0xd1, 0x44, 0x63, 0xb9, 0xc6, 0x92, 0xc6, 0x16, 0x3b, 0x5f, 0xb5, 0xc2, 0xdd, 0xbc, 0x32, + 0xc2, 0xcd, 0x60, 0xa3, 0xf4, 0xf3, 0x30, 0xf8, 0x42, 0x21, 0x8c, 0xfa, 0x71, 0x09, 0x9c, 0xcb, + 0x54, 0xeb, 0x2f, 0xf1, 0x06, 0x33, 0x73, 0x38, 0x9a, 0x3c, 0xc6, 0xe1, 0x68, 0x15, 0xcc, 0x8b, + 0x67, 0xef, 0xd4, 0xd9, 0x2a, 0x0c, 0x93, 0x76, 0x52, 0x8c, 0xd2, 0xfa, 0xb2, 0x1b, 0xd4, 0xd2, + 0x31, 0x6f, 0x50, 0xe3, 0x5e, 0x88, 0x7f, 0x6b, 0xf9, 0xf9, 0x9c, 0xf5, 0x42, 0xfc, 0x69, 0x2b, + 0xad, 0x0f, 0xdf, 0x0c, 0x92, 0x35, 0x44, 0x98, 0xe6, 0x08, 0xa9, 0xec, 0x0b, 0x01, 0x52, 0xda, + 0x4f, 0xf4, 0xb4, 0xfb, 0xbe, 0xe4, 0x69, 0x77, 0x65, 0x44, 0x98, 0x8d, 0x7f, 0xc3, 0x29, 0x3d, + 0xbf, 0x56, 0x8e, 0x7f, 0x7e, 0x55, 0xff, 0xa2, 0x80, 0xe7, 0x72, 0xb7, 0x29, 0xb8, 0x9a, 0x60, + 0x8f, 0xd7, 0x52, 0xec, 0xf1, 0xf9, 0x5c, 0xc3, 0x18, 0x85, 0x34, 0xe5, 0x97, 0x9f, 0x37, 0x47, + 0x5e, 0x7e, 0x4a, 0x4e, 0x22, 0xa3, 0x6f, 0x41, 0x5b, 0xaf, 0x3f, 0x7c, 0x54, 0x9b, 0xf8, 0xf4, + 0x51, 0x6d, 0xe2, 0xb3, 0x47, 0xb5, 0x89, 0x9f, 0x0f, 0x6b, 0xca, 0xc3, 0x61, 0x4d, 0xf9, 0x74, + 0x58, 0x53, 0x3e, 0x1b, 0xd6, 0x94, 0xbf, 0x0f, 0x6b, 0xca, 0xaf, 0x3f, 0xaf, 0x4d, 0xdc, 0x85, + 0xd9, 0xff, 0x8a, 0xfe, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x5f, 0x0a, 0xea, 0xf9, 0x40, 0x2a, 0x00, + 0x00, } func (m *ControllerRevision) Marshal() (dAtA []byte, err error) { @@ -1748,6 +1750,11 @@ func (m *DeploymentStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.TerminatingReplicas != nil { + i = encodeVarintGenerated(dAtA, i, uint64(*m.TerminatingReplicas)) + i-- + dAtA[i] = 0x48 + } if m.CollisionCount != nil { i = encodeVarintGenerated(dAtA, i, uint64(*m.CollisionCount)) i-- @@ -2054,6 +2061,11 @@ func (m *ReplicaSetStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.TerminatingReplicas != nil { + i = encodeVarintGenerated(dAtA, i, uint64(*m.TerminatingReplicas)) + i-- + dAtA[i] = 0x38 + } if len(m.Conditions) > 0 { for iNdEx := len(m.Conditions) - 1; iNdEx >= 0; iNdEx-- { { @@ -2915,6 +2927,9 @@ func (m *DeploymentStatus) Size() (n int) { if m.CollisionCount != nil { n += 1 + sovGenerated(uint64(*m.CollisionCount)) } + if m.TerminatingReplicas != nil { + n += 1 + sovGenerated(uint64(*m.TerminatingReplicas)) + } return n } @@ -3020,6 +3035,9 @@ func (m *ReplicaSetStatus) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) } } + if m.TerminatingReplicas != nil { + n += 1 + sovGenerated(uint64(*m.TerminatingReplicas)) + } return n } @@ -3435,6 +3453,7 @@ func (this *DeploymentStatus) String() string { `Conditions:` + repeatedStringForConditions + `,`, `ReadyReplicas:` + fmt.Sprintf("%v", this.ReadyReplicas) + `,`, `CollisionCount:` + valueToStringGenerated(this.CollisionCount) + `,`, + `TerminatingReplicas:` + valueToStringGenerated(this.TerminatingReplicas) + `,`, `}`, }, "") return s @@ -3521,6 +3540,7 @@ func (this *ReplicaSetStatus) String() string { `ReadyReplicas:` + fmt.Sprintf("%v", this.ReadyReplicas) + `,`, `AvailableReplicas:` + fmt.Sprintf("%v", this.AvailableReplicas) + `,`, `Conditions:` + repeatedStringForConditions + `,`, + `TerminatingReplicas:` + valueToStringGenerated(this.TerminatingReplicas) + `,`, `}`, }, "") return s @@ -5941,6 +5961,26 @@ func (m *DeploymentStatus) Unmarshal(dAtA []byte) error { } } m.CollisionCount = &v + case 9: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TerminatingReplicas", wireType) + } + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.TerminatingReplicas = &v default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -6873,6 +6913,26 @@ func (m *ReplicaSetStatus) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TerminatingReplicas", wireType) + } + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.TerminatingReplicas = &v default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/go-controller/vendor/k8s.io/api/apps/v1/generated.proto b/go-controller/vendor/k8s.io/api/apps/v1/generated.proto index 388e638f4d..38c8997e99 100644 --- a/go-controller/vendor/k8s.io/api/apps/v1/generated.proto +++ b/go-controller/vendor/k8s.io/api/apps/v1/generated.proto @@ -318,19 +318,19 @@ message DeploymentStatus { // +optional optional int64 observedGeneration = 1; - // Total number of non-terminated pods targeted by this deployment (their labels match the selector). + // Total number of non-terminating pods targeted by this deployment (their labels match the selector). // +optional optional int32 replicas = 2; - // Total number of non-terminated pods targeted by this deployment that have the desired template spec. + // Total number of non-terminating pods targeted by this deployment that have the desired template spec. // +optional optional int32 updatedReplicas = 3; - // readyReplicas is the number of pods targeted by this Deployment with a Ready Condition. + // Total number of non-terminating pods targeted by this Deployment with a Ready Condition. // +optional optional int32 readyReplicas = 7; - // Total number of available pods (ready for at least minReadySeconds) targeted by this deployment. + // Total number of available non-terminating pods (ready for at least minReadySeconds) targeted by this deployment. // +optional optional int32 availableReplicas = 4; @@ -340,6 +340,13 @@ message DeploymentStatus { // +optional optional int32 unavailableReplicas = 5; + // Total number of terminating pods targeted by this deployment. Terminating pods have a non-null + // .metadata.deletionTimestamp and have not yet reached the Failed or Succeeded .status.phase. + // + // This is an alpha field. Enable DeploymentReplicaSetTerminatingReplicas to be able to use this field. + // +optional + optional int32 terminatingReplicas = 9; + // Represents the latest available observations of a deployment's current state. // +patchMergeKey=type // +patchStrategy=merge @@ -421,16 +428,16 @@ message ReplicaSetList { optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; // List of ReplicaSets. - // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller + // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset repeated ReplicaSet items = 2; } // ReplicaSetSpec is the specification of a ReplicaSet. message ReplicaSetSpec { - // Replicas is the number of desired replicas. + // Replicas is the number of desired pods. // This is a pointer to distinguish between explicit zero and unspecified. // Defaults to 1. - // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller + // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset // +optional optional int32 replicas = 1; @@ -448,29 +455,36 @@ message ReplicaSetSpec { // Template is the object that describes the pod that will be created if // insufficient replicas are detected. - // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template + // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/#pod-template // +optional optional .k8s.io.api.core.v1.PodTemplateSpec template = 3; } // ReplicaSetStatus represents the current status of a ReplicaSet. message ReplicaSetStatus { - // Replicas is the most recently observed number of replicas. - // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller + // Replicas is the most recently observed number of non-terminating pods. + // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset optional int32 replicas = 1; - // The number of pods that have labels matching the labels of the pod template of the replicaset. + // The number of non-terminating pods that have labels matching the labels of the pod template of the replicaset. // +optional optional int32 fullyLabeledReplicas = 2; - // readyReplicas is the number of pods targeted by this ReplicaSet with a Ready Condition. + // The number of non-terminating pods targeted by this ReplicaSet with a Ready Condition. // +optional optional int32 readyReplicas = 4; - // The number of available replicas (ready for at least minReadySeconds) for this replica set. + // The number of available non-terminating pods (ready for at least minReadySeconds) for this replica set. // +optional optional int32 availableReplicas = 5; + // The number of terminating pods for this replica set. Terminating pods have a non-null .metadata.deletionTimestamp + // and have not yet reached the Failed or Succeeded .status.phase. + // + // This is an alpha field. Enable DeploymentReplicaSetTerminatingReplicas to be able to use this field. + // +optional + optional int32 terminatingReplicas = 7; + // ObservedGeneration reflects the generation of the most recently observed ReplicaSet. // +optional optional int64 observedGeneration = 3; @@ -702,6 +716,7 @@ message StatefulSetSpec { // the network identity of the set. Pods get DNS/hostnames that follow the // pattern: pod-specific-string.serviceName.default.svc.cluster.local // where "pod-specific-string" is managed by the StatefulSet controller. + // +optional optional string serviceName = 5; // podManagementPolicy controls how pods are created during initial scale up, diff --git a/go-controller/vendor/k8s.io/api/apps/v1/types.go b/go-controller/vendor/k8s.io/api/apps/v1/types.go index a68690b447..1362d875d8 100644 --- a/go-controller/vendor/k8s.io/api/apps/v1/types.go +++ b/go-controller/vendor/k8s.io/api/apps/v1/types.go @@ -220,6 +220,7 @@ type StatefulSetSpec struct { // the network identity of the set. Pods get DNS/hostnames that follow the // pattern: pod-specific-string.serviceName.default.svc.cluster.local // where "pod-specific-string" is managed by the StatefulSet controller. + // +optional ServiceName string `json:"serviceName" protobuf:"bytes,5,opt,name=serviceName"` // podManagementPolicy controls how pods are created during initial scale up, @@ -486,19 +487,19 @@ type DeploymentStatus struct { // +optional ObservedGeneration int64 `json:"observedGeneration,omitempty" protobuf:"varint,1,opt,name=observedGeneration"` - // Total number of non-terminated pods targeted by this deployment (their labels match the selector). + // Total number of non-terminating pods targeted by this deployment (their labels match the selector). // +optional Replicas int32 `json:"replicas,omitempty" protobuf:"varint,2,opt,name=replicas"` - // Total number of non-terminated pods targeted by this deployment that have the desired template spec. + // Total number of non-terminating pods targeted by this deployment that have the desired template spec. // +optional UpdatedReplicas int32 `json:"updatedReplicas,omitempty" protobuf:"varint,3,opt,name=updatedReplicas"` - // readyReplicas is the number of pods targeted by this Deployment with a Ready Condition. + // Total number of non-terminating pods targeted by this Deployment with a Ready Condition. // +optional ReadyReplicas int32 `json:"readyReplicas,omitempty" protobuf:"varint,7,opt,name=readyReplicas"` - // Total number of available pods (ready for at least minReadySeconds) targeted by this deployment. + // Total number of available non-terminating pods (ready for at least minReadySeconds) targeted by this deployment. // +optional AvailableReplicas int32 `json:"availableReplicas,omitempty" protobuf:"varint,4,opt,name=availableReplicas"` @@ -508,6 +509,13 @@ type DeploymentStatus struct { // +optional UnavailableReplicas int32 `json:"unavailableReplicas,omitempty" protobuf:"varint,5,opt,name=unavailableReplicas"` + // Total number of terminating pods targeted by this deployment. Terminating pods have a non-null + // .metadata.deletionTimestamp and have not yet reached the Failed or Succeeded .status.phase. + // + // This is an alpha field. Enable DeploymentReplicaSetTerminatingReplicas to be able to use this field. + // +optional + TerminatingReplicas *int32 `json:"terminatingReplicas,omitempty" protobuf:"varint,9,opt,name=terminatingReplicas"` + // Represents the latest available observations of a deployment's current state. // +patchMergeKey=type // +patchStrategy=merge @@ -839,16 +847,16 @@ type ReplicaSetList struct { metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` // List of ReplicaSets. - // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller + // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset Items []ReplicaSet `json:"items" protobuf:"bytes,2,rep,name=items"` } // ReplicaSetSpec is the specification of a ReplicaSet. type ReplicaSetSpec struct { - // Replicas is the number of desired replicas. + // Replicas is the number of desired pods. // This is a pointer to distinguish between explicit zero and unspecified. // Defaults to 1. - // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller + // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset // +optional Replicas *int32 `json:"replicas,omitempty" protobuf:"varint,1,opt,name=replicas"` @@ -866,29 +874,36 @@ type ReplicaSetSpec struct { // Template is the object that describes the pod that will be created if // insufficient replicas are detected. - // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template + // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/#pod-template // +optional Template v1.PodTemplateSpec `json:"template,omitempty" protobuf:"bytes,3,opt,name=template"` } // ReplicaSetStatus represents the current status of a ReplicaSet. type ReplicaSetStatus struct { - // Replicas is the most recently observed number of replicas. - // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller + // Replicas is the most recently observed number of non-terminating pods. + // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset Replicas int32 `json:"replicas" protobuf:"varint,1,opt,name=replicas"` - // The number of pods that have labels matching the labels of the pod template of the replicaset. + // The number of non-terminating pods that have labels matching the labels of the pod template of the replicaset. // +optional FullyLabeledReplicas int32 `json:"fullyLabeledReplicas,omitempty" protobuf:"varint,2,opt,name=fullyLabeledReplicas"` - // readyReplicas is the number of pods targeted by this ReplicaSet with a Ready Condition. + // The number of non-terminating pods targeted by this ReplicaSet with a Ready Condition. // +optional ReadyReplicas int32 `json:"readyReplicas,omitempty" protobuf:"varint,4,opt,name=readyReplicas"` - // The number of available replicas (ready for at least minReadySeconds) for this replica set. + // The number of available non-terminating pods (ready for at least minReadySeconds) for this replica set. // +optional AvailableReplicas int32 `json:"availableReplicas,omitempty" protobuf:"varint,5,opt,name=availableReplicas"` + // The number of terminating pods for this replica set. Terminating pods have a non-null .metadata.deletionTimestamp + // and have not yet reached the Failed or Succeeded .status.phase. + // + // This is an alpha field. Enable DeploymentReplicaSetTerminatingReplicas to be able to use this field. + // +optional + TerminatingReplicas *int32 `json:"terminatingReplicas,omitempty" protobuf:"varint,7,opt,name=terminatingReplicas"` + // ObservedGeneration reflects the generation of the most recently observed ReplicaSet. // +optional ObservedGeneration int64 `json:"observedGeneration,omitempty" protobuf:"varint,3,opt,name=observedGeneration"` diff --git a/go-controller/vendor/k8s.io/api/apps/v1/types_swagger_doc_generated.go b/go-controller/vendor/k8s.io/api/apps/v1/types_swagger_doc_generated.go index 341ecdadb2..f44ba7bc33 100644 --- a/go-controller/vendor/k8s.io/api/apps/v1/types_swagger_doc_generated.go +++ b/go-controller/vendor/k8s.io/api/apps/v1/types_swagger_doc_generated.go @@ -177,11 +177,12 @@ func (DeploymentSpec) SwaggerDoc() map[string]string { var map_DeploymentStatus = map[string]string{ "": "DeploymentStatus is the most recently observed status of the Deployment.", "observedGeneration": "The generation observed by the deployment controller.", - "replicas": "Total number of non-terminated pods targeted by this deployment (their labels match the selector).", - "updatedReplicas": "Total number of non-terminated pods targeted by this deployment that have the desired template spec.", - "readyReplicas": "readyReplicas is the number of pods targeted by this Deployment with a Ready Condition.", - "availableReplicas": "Total number of available pods (ready for at least minReadySeconds) targeted by this deployment.", + "replicas": "Total number of non-terminating pods targeted by this deployment (their labels match the selector).", + "updatedReplicas": "Total number of non-terminating pods targeted by this deployment that have the desired template spec.", + "readyReplicas": "Total number of non-terminating pods targeted by this Deployment with a Ready Condition.", + "availableReplicas": "Total number of available non-terminating pods (ready for at least minReadySeconds) targeted by this deployment.", "unavailableReplicas": "Total number of unavailable pods targeted by this deployment. This is the total number of pods that are still required for the deployment to have 100% available capacity. They may either be pods that are running but not yet available or pods that still have not been created.", + "terminatingReplicas": "Total number of terminating pods targeted by this deployment. Terminating pods have a non-null .metadata.deletionTimestamp and have not yet reached the Failed or Succeeded .status.phase.\n\nThis is an alpha field. Enable DeploymentReplicaSetTerminatingReplicas to be able to use this field.", "conditions": "Represents the latest available observations of a deployment's current state.", "collisionCount": "Count of hash collisions for the Deployment. The Deployment controller uses this field as a collision avoidance mechanism when it needs to create the name for the newest ReplicaSet.", } @@ -227,7 +228,7 @@ func (ReplicaSetCondition) SwaggerDoc() map[string]string { var map_ReplicaSetList = map[string]string{ "": "ReplicaSetList is a collection of ReplicaSets.", "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "items": "List of ReplicaSets. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller", + "items": "List of ReplicaSets. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset", } func (ReplicaSetList) SwaggerDoc() map[string]string { @@ -236,10 +237,10 @@ func (ReplicaSetList) SwaggerDoc() map[string]string { var map_ReplicaSetSpec = map[string]string{ "": "ReplicaSetSpec is the specification of a ReplicaSet.", - "replicas": "Replicas is the number of desired replicas. This is a pointer to distinguish between explicit zero and unspecified. Defaults to 1. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller", + "replicas": "Replicas is the number of desired pods. This is a pointer to distinguish between explicit zero and unspecified. Defaults to 1. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset", "minReadySeconds": "Minimum number of seconds for which a newly created pod should be ready without any of its container crashing, for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready)", "selector": "Selector is a label query over pods that should match the replica count. Label keys and values that must match in order to be controlled by this replica set. It must match the pod template's labels. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors", - "template": "Template is the object that describes the pod that will be created if insufficient replicas are detected. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template", + "template": "Template is the object that describes the pod that will be created if insufficient replicas are detected. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/#pod-template", } func (ReplicaSetSpec) SwaggerDoc() map[string]string { @@ -248,10 +249,11 @@ func (ReplicaSetSpec) SwaggerDoc() map[string]string { var map_ReplicaSetStatus = map[string]string{ "": "ReplicaSetStatus represents the current status of a ReplicaSet.", - "replicas": "Replicas is the most recently observed number of replicas. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller", - "fullyLabeledReplicas": "The number of pods that have labels matching the labels of the pod template of the replicaset.", - "readyReplicas": "readyReplicas is the number of pods targeted by this ReplicaSet with a Ready Condition.", - "availableReplicas": "The number of available replicas (ready for at least minReadySeconds) for this replica set.", + "replicas": "Replicas is the most recently observed number of non-terminating pods. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset", + "fullyLabeledReplicas": "The number of non-terminating pods that have labels matching the labels of the pod template of the replicaset.", + "readyReplicas": "The number of non-terminating pods targeted by this ReplicaSet with a Ready Condition.", + "availableReplicas": "The number of available non-terminating pods (ready for at least minReadySeconds) for this replica set.", + "terminatingReplicas": "The number of terminating pods for this replica set. Terminating pods have a non-null .metadata.deletionTimestamp and have not yet reached the Failed or Succeeded .status.phase.\n\nThis is an alpha field. Enable DeploymentReplicaSetTerminatingReplicas to be able to use this field.", "observedGeneration": "ObservedGeneration reflects the generation of the most recently observed ReplicaSet.", "conditions": "Represents the latest available observations of a replica set's current state.", } diff --git a/go-controller/vendor/k8s.io/api/apps/v1/zz_generated.deepcopy.go b/go-controller/vendor/k8s.io/api/apps/v1/zz_generated.deepcopy.go index 6912986ac3..9e67658ba6 100644 --- a/go-controller/vendor/k8s.io/api/apps/v1/zz_generated.deepcopy.go +++ b/go-controller/vendor/k8s.io/api/apps/v1/zz_generated.deepcopy.go @@ -363,6 +363,11 @@ func (in *DeploymentSpec) DeepCopy() *DeploymentSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DeploymentStatus) DeepCopyInto(out *DeploymentStatus) { *out = *in + if in.TerminatingReplicas != nil { + in, out := &in.TerminatingReplicas, &out.TerminatingReplicas + *out = new(int32) + **out = **in + } if in.Conditions != nil { in, out := &in.Conditions, &out.Conditions *out = make([]DeploymentCondition, len(*in)) @@ -517,6 +522,11 @@ func (in *ReplicaSetSpec) DeepCopy() *ReplicaSetSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ReplicaSetStatus) DeepCopyInto(out *ReplicaSetStatus) { *out = *in + if in.TerminatingReplicas != nil { + in, out := &in.TerminatingReplicas, &out.TerminatingReplicas + *out = new(int32) + **out = **in + } if in.Conditions != nil { in, out := &in.Conditions, &out.Conditions *out = make([]ReplicaSetCondition, len(*in)) diff --git a/go-controller/vendor/k8s.io/api/apps/v1beta1/doc.go b/go-controller/vendor/k8s.io/api/apps/v1beta1/doc.go index 38a358551a..7770fab5d2 100644 --- a/go-controller/vendor/k8s.io/api/apps/v1beta1/doc.go +++ b/go-controller/vendor/k8s.io/api/apps/v1beta1/doc.go @@ -19,4 +19,4 @@ limitations under the License. // +k8s:openapi-gen=true // +k8s:prerelease-lifecycle-gen=true -package v1beta1 // import "k8s.io/api/apps/v1beta1" +package v1beta1 diff --git a/go-controller/vendor/k8s.io/api/apps/v1beta1/generated.pb.go b/go-controller/vendor/k8s.io/api/apps/v1beta1/generated.pb.go index 76e755b4a3..ae84aaf487 100644 --- a/go-controller/vendor/k8s.io/api/apps/v1beta1/generated.pb.go +++ b/go-controller/vendor/k8s.io/api/apps/v1beta1/generated.pb.go @@ -728,134 +728,135 @@ func init() { } var fileDescriptor_2747f709ac7c95e7 = []byte{ - // 2018 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x59, 0xcd, 0x6f, 0x1b, 0xc7, - 0x15, 0xf7, 0x52, 0xa2, 0x44, 0x3d, 0x45, 0x94, 0x3d, 0x52, 0x2d, 0x46, 0x69, 0x25, 0x61, 0x63, - 0xc4, 0x4a, 0x62, 0x2f, 0x63, 0x25, 0x0d, 0x12, 0xbb, 0x75, 0x21, 0x4a, 0x6e, 0xec, 0x40, 0x8a, - 0x94, 0x91, 0x64, 0xa3, 0xe9, 0x07, 0x32, 0x22, 0xc7, 0xd4, 0x46, 0xfb, 0x85, 0xdd, 0x21, 0x63, - 0xa2, 0x97, 0xfe, 0x01, 0x05, 0xd2, 0x73, 0xff, 0x8a, 0xf6, 0xd4, 0xa2, 0x45, 0x2f, 0x3d, 0x14, - 0x3e, 0x06, 0xbd, 0x34, 0x27, 0xa2, 0x66, 0xae, 0xed, 0xad, 0xbd, 0x18, 0x28, 0x50, 0xcc, 0xec, - 0xec, 0xf7, 0xae, 0xb4, 0x2c, 0x60, 0x01, 0xcd, 0x8d, 0x3b, 0xef, 0xbd, 0xdf, 0x7b, 0xf3, 0xe6, - 0xbd, 0x37, 0xef, 0x0d, 0xe1, 0xfa, 0xe9, 0x7b, 0x9e, 0xa6, 0xdb, 0x4d, 0xe2, 0xe8, 0x4d, 0xe2, - 0x38, 0x5e, 0xb3, 0x7f, 0xeb, 0x98, 0x32, 0x72, 0xab, 0xd9, 0xa5, 0x16, 0x75, 0x09, 0xa3, 0x1d, - 0xcd, 0x71, 0x6d, 0x66, 0xa3, 0x25, 0x9f, 0x51, 0x23, 0x8e, 0xae, 0x71, 0x46, 0x4d, 0x32, 0x2e, - 0xdf, 0xec, 0xea, 0xec, 0xa4, 0x77, 0xac, 0xb5, 0x6d, 0xb3, 0xd9, 0xb5, 0xbb, 0x76, 0x53, 0xf0, - 0x1f, 0xf7, 0x1e, 0x8b, 0x2f, 0xf1, 0x21, 0x7e, 0xf9, 0x38, 0xcb, 0x6a, 0x4c, 0x61, 0xdb, 0x76, - 0x69, 0xb3, 0x9f, 0xd1, 0xb5, 0xfc, 0x4e, 0xc4, 0x63, 0x92, 0xf6, 0x89, 0x6e, 0x51, 0x77, 0xd0, - 0x74, 0x4e, 0xbb, 0x7c, 0xc1, 0x6b, 0x9a, 0x94, 0x91, 0x3c, 0xa9, 0x66, 0x91, 0x94, 0xdb, 0xb3, - 0x98, 0x6e, 0xd2, 0x8c, 0xc0, 0xbb, 0xe7, 0x09, 0x78, 0xed, 0x13, 0x6a, 0x92, 0x8c, 0xdc, 0xdb, - 0x45, 0x72, 0x3d, 0xa6, 0x1b, 0x4d, 0xdd, 0x62, 0x1e, 0x73, 0xd3, 0x42, 0xea, 0xbf, 0x15, 0x40, - 0x5b, 0xb6, 0xc5, 0x5c, 0xdb, 0x30, 0xa8, 0x8b, 0x69, 0x5f, 0xf7, 0x74, 0xdb, 0x42, 0x9f, 0x42, - 0x8d, 0xef, 0xa7, 0x43, 0x18, 0x69, 0x28, 0x6b, 0xca, 0xfa, 0xec, 0xc6, 0x5b, 0x5a, 0xe4, 0xe9, - 0x10, 0x5e, 0x73, 0x4e, 0xbb, 0x7c, 0xc1, 0xd3, 0x38, 0xb7, 0xd6, 0xbf, 0xa5, 0xed, 0x1d, 0x7f, - 0x46, 0xdb, 0x6c, 0x97, 0x32, 0xd2, 0x42, 0x4f, 0x87, 0xab, 0x97, 0x46, 0xc3, 0x55, 0x88, 0xd6, - 0x70, 0x88, 0x8a, 0xf6, 0x60, 0x52, 0xa0, 0x57, 0x04, 0xfa, 0xcd, 0x42, 0x74, 0xb9, 0x69, 0x0d, - 0x93, 0xcf, 0xef, 0x3d, 0x61, 0xd4, 0xe2, 0xe6, 0xb5, 0x5e, 0x92, 0xd0, 0x93, 0xdb, 0x84, 0x11, - 0x2c, 0x80, 0xd0, 0x0d, 0xa8, 0xb9, 0xd2, 0xfc, 0xc6, 0xc4, 0x9a, 0xb2, 0x3e, 0xd1, 0xba, 0x2c, - 0xb9, 0x6a, 0xc1, 0xb6, 0x70, 0xc8, 0xa1, 0x3e, 0x55, 0xe0, 0x6a, 0x76, 0xdf, 0x3b, 0xba, 0xc7, - 0xd0, 0x4f, 0x32, 0x7b, 0xd7, 0xca, 0xed, 0x9d, 0x4b, 0x8b, 0x9d, 0x87, 0x8a, 0x83, 0x95, 0xd8, - 0xbe, 0xf7, 0xa1, 0xaa, 0x33, 0x6a, 0x7a, 0x8d, 0xca, 0xda, 0xc4, 0xfa, 0xec, 0xc6, 0x9b, 0x5a, - 0x41, 0x00, 0x6b, 0x59, 0xeb, 0x5a, 0x73, 0x12, 0xb7, 0xfa, 0x80, 0x23, 0x60, 0x1f, 0x48, 0xfd, - 0x65, 0x05, 0x60, 0x9b, 0x3a, 0x86, 0x3d, 0x30, 0xa9, 0xc5, 0x2e, 0xe0, 0xe8, 0x1e, 0xc0, 0xa4, - 0xe7, 0xd0, 0xb6, 0x3c, 0xba, 0xeb, 0x85, 0x3b, 0x88, 0x8c, 0x3a, 0x70, 0x68, 0x3b, 0x3a, 0x34, - 0xfe, 0x85, 0x05, 0x04, 0xfa, 0x18, 0xa6, 0x3c, 0x46, 0x58, 0xcf, 0x13, 0x47, 0x36, 0xbb, 0xf1, - 0x7a, 0x19, 0x30, 0x21, 0xd0, 0xaa, 0x4b, 0xb8, 0x29, 0xff, 0x1b, 0x4b, 0x20, 0xf5, 0x6f, 0x13, - 0xb0, 0x10, 0x31, 0x6f, 0xd9, 0x56, 0x47, 0x67, 0x3c, 0xa4, 0xef, 0xc0, 0x24, 0x1b, 0x38, 0x54, - 0xf8, 0x64, 0xa6, 0x75, 0x3d, 0x30, 0xe6, 0x70, 0xe0, 0xd0, 0xe7, 0xc3, 0xd5, 0xa5, 0x1c, 0x11, - 0x4e, 0xc2, 0x42, 0x08, 0xed, 0x84, 0x76, 0x56, 0x84, 0xf8, 0x3b, 0x49, 0xe5, 0xcf, 0x87, 0xab, - 0x39, 0x05, 0x44, 0x0b, 0x91, 0x92, 0x26, 0xa2, 0xcf, 0xa0, 0x6e, 0x10, 0x8f, 0x1d, 0x39, 0x1d, - 0xc2, 0xe8, 0xa1, 0x6e, 0xd2, 0xc6, 0x94, 0xd8, 0xfd, 0x1b, 0xe5, 0x0e, 0x8a, 0x4b, 0xb4, 0xae, - 0x4a, 0x0b, 0xea, 0x3b, 0x09, 0x24, 0x9c, 0x42, 0x46, 0x7d, 0x40, 0x7c, 0xe5, 0xd0, 0x25, 0x96, - 0xe7, 0xef, 0x8a, 0xeb, 0x9b, 0x1e, 0x5b, 0xdf, 0xb2, 0xd4, 0x87, 0x76, 0x32, 0x68, 0x38, 0x47, - 0x03, 0x7a, 0x0d, 0xa6, 0x5c, 0x4a, 0x3c, 0xdb, 0x6a, 0x4c, 0x0a, 0x8f, 0x85, 0xc7, 0x85, 0xc5, - 0x2a, 0x96, 0x54, 0xf4, 0x3a, 0x4c, 0x9b, 0xd4, 0xf3, 0x48, 0x97, 0x36, 0xaa, 0x82, 0x71, 0x5e, - 0x32, 0x4e, 0xef, 0xfa, 0xcb, 0x38, 0xa0, 0xab, 0xbf, 0x57, 0xa0, 0x1e, 0x1d, 0xd3, 0x05, 0xe4, - 0xea, 0xfd, 0x64, 0xae, 0xbe, 0x5a, 0x22, 0x38, 0x0b, 0x72, 0xf4, 0x1f, 0x15, 0x40, 0x11, 0x13, - 0xb6, 0x0d, 0xe3, 0x98, 0xb4, 0x4f, 0xd1, 0x1a, 0x4c, 0x5a, 0xc4, 0x0c, 0x62, 0x32, 0x4c, 0x90, - 0x8f, 0x88, 0x49, 0xb1, 0xa0, 0xa0, 0x2f, 0x14, 0x40, 0x3d, 0x71, 0x9a, 0x9d, 0x4d, 0xcb, 0xb2, - 0x19, 0xe1, 0x0e, 0x0e, 0x0c, 0xda, 0x2a, 0x61, 0x50, 0xa0, 0x4b, 0x3b, 0xca, 0xa0, 0xdc, 0xb3, - 0x98, 0x3b, 0x88, 0x0e, 0x36, 0xcb, 0x80, 0x73, 0x54, 0xa3, 0x1f, 0x03, 0xb8, 0x12, 0xf3, 0xd0, - 0x96, 0x69, 0x5b, 0x5c, 0x03, 0x02, 0xf5, 0x5b, 0xb6, 0xf5, 0x58, 0xef, 0x46, 0x85, 0x05, 0x87, - 0x10, 0x38, 0x06, 0xb7, 0x7c, 0x0f, 0x96, 0x0a, 0xec, 0x44, 0x97, 0x61, 0xe2, 0x94, 0x0e, 0x7c, - 0x57, 0x61, 0xfe, 0x13, 0x2d, 0x42, 0xb5, 0x4f, 0x8c, 0x1e, 0xf5, 0x73, 0x12, 0xfb, 0x1f, 0xb7, - 0x2b, 0xef, 0x29, 0xea, 0x6f, 0xaa, 0xf1, 0x48, 0xe1, 0xf5, 0x06, 0xad, 0xf3, 0xeb, 0xc1, 0x31, - 0xf4, 0x36, 0xf1, 0x04, 0x46, 0xb5, 0xf5, 0x92, 0x7f, 0x35, 0xf8, 0x6b, 0x38, 0xa4, 0xa2, 0x9f, - 0x42, 0xcd, 0xa3, 0x06, 0x6d, 0x33, 0xdb, 0x95, 0x25, 0xee, 0xed, 0x92, 0x31, 0x45, 0x8e, 0xa9, - 0x71, 0x20, 0x45, 0x7d, 0xf8, 0xe0, 0x0b, 0x87, 0x90, 0xe8, 0x63, 0xa8, 0x31, 0x6a, 0x3a, 0x06, - 0x61, 0x54, 0x7a, 0x2f, 0x11, 0x57, 0xbc, 0x76, 0x70, 0xb0, 0x7d, 0xbb, 0x73, 0x28, 0xd9, 0x44, - 0xf5, 0x0c, 0xe3, 0x34, 0x58, 0xc5, 0x21, 0x0c, 0xfa, 0x11, 0xd4, 0x3c, 0xc6, 0x6f, 0xf5, 0xee, - 0x40, 0x64, 0xdb, 0x59, 0xd7, 0x4a, 0xbc, 0x8e, 0xfa, 0x22, 0x11, 0x74, 0xb0, 0x82, 0x43, 0x38, - 0xb4, 0x09, 0xf3, 0xa6, 0x6e, 0x61, 0x4a, 0x3a, 0x83, 0x03, 0xda, 0xb6, 0xad, 0x8e, 0x27, 0xd2, - 0xb4, 0xda, 0x5a, 0x92, 0x42, 0xf3, 0xbb, 0x49, 0x32, 0x4e, 0xf3, 0xa3, 0x1d, 0x58, 0x0c, 0xae, - 0xdd, 0xfb, 0xba, 0xc7, 0x6c, 0x77, 0xb0, 0xa3, 0x9b, 0x3a, 0x13, 0x35, 0xaf, 0xda, 0x6a, 0x8c, - 0x86, 0xab, 0x8b, 0x38, 0x87, 0x8e, 0x73, 0xa5, 0x78, 0x5d, 0x71, 0x48, 0xcf, 0xa3, 0x1d, 0x51, - 0xc3, 0x6a, 0x51, 0x5d, 0xd9, 0x17, 0xab, 0x58, 0x52, 0xd1, 0xa3, 0x44, 0x98, 0xd6, 0xc6, 0x0b, - 0xd3, 0x7a, 0x71, 0x88, 0xa2, 0x23, 0x58, 0x72, 0x5c, 0xbb, 0xeb, 0x52, 0xcf, 0xdb, 0xa6, 0xa4, - 0x63, 0xe8, 0x16, 0x0d, 0x3c, 0x33, 0x23, 0x76, 0xf4, 0xca, 0x68, 0xb8, 0xba, 0xb4, 0x9f, 0xcf, - 0x82, 0x8b, 0x64, 0xd5, 0x3f, 0x4f, 0xc2, 0xe5, 0xf4, 0x1d, 0x87, 0x3e, 0x04, 0x64, 0x1f, 0x7b, - 0xd4, 0xed, 0xd3, 0xce, 0x07, 0x7e, 0xe3, 0xc6, 0xbb, 0x1b, 0x45, 0x74, 0x37, 0x61, 0xde, 0xee, - 0x65, 0x38, 0x70, 0x8e, 0x94, 0xdf, 0x1f, 0xc9, 0x04, 0xa8, 0x08, 0x43, 0x63, 0xfd, 0x51, 0x26, - 0x09, 0x36, 0x61, 0x5e, 0xe6, 0x7e, 0x40, 0x14, 0xc1, 0x1a, 0x3b, 0xf7, 0xa3, 0x24, 0x19, 0xa7, - 0xf9, 0xd1, 0x1d, 0x98, 0x73, 0x79, 0x1c, 0x84, 0x00, 0xd3, 0x02, 0xe0, 0x5b, 0x12, 0x60, 0x0e, - 0xc7, 0x89, 0x38, 0xc9, 0x8b, 0x3e, 0x80, 0x2b, 0xa4, 0x4f, 0x74, 0x83, 0x1c, 0x1b, 0x34, 0x04, - 0x98, 0x14, 0x00, 0x2f, 0x4b, 0x80, 0x2b, 0x9b, 0x69, 0x06, 0x9c, 0x95, 0x41, 0xbb, 0xb0, 0xd0, - 0xb3, 0xb2, 0x50, 0x7e, 0x10, 0xbf, 0x22, 0xa1, 0x16, 0x8e, 0xb2, 0x2c, 0x38, 0x4f, 0x0e, 0x7d, - 0x0a, 0xd0, 0x0e, 0x6e, 0x75, 0xaf, 0x31, 0x25, 0xca, 0xf0, 0x8d, 0x12, 0xc9, 0x16, 0xb6, 0x02, - 0x51, 0x09, 0x0c, 0x97, 0x3c, 0x1c, 0xc3, 0x44, 0xb7, 0xa1, 0xde, 0xb6, 0x0d, 0x43, 0x44, 0xfe, - 0x96, 0xdd, 0xb3, 0x98, 0x08, 0xde, 0x6a, 0x0b, 0xf1, 0xcb, 0x7e, 0x2b, 0x41, 0xc1, 0x29, 0x4e, - 0xf5, 0x8f, 0x4a, 0xfc, 0x9a, 0x09, 0xd2, 0x19, 0xdd, 0x4e, 0xb4, 0x3e, 0xaf, 0xa5, 0x5a, 0x9f, - 0xab, 0x59, 0x89, 0x58, 0xe7, 0xa3, 0xc3, 0x1c, 0x0f, 0x7e, 0xdd, 0xea, 0xfa, 0x07, 0x2e, 0x4b, - 0xe2, 0x5b, 0x67, 0xa6, 0x52, 0xc8, 0x1d, 0xbb, 0x18, 0xaf, 0x88, 0x33, 0x8f, 0x13, 0x71, 0x12, - 0x59, 0xbd, 0x0b, 0xf5, 0x64, 0x1e, 0x26, 0x7a, 0x7a, 0xe5, 0xdc, 0x9e, 0xfe, 0x6b, 0x05, 0x96, - 0x0a, 0xb4, 0x23, 0x03, 0xea, 0x26, 0x79, 0x12, 0x3b, 0xe6, 0x73, 0x7b, 0x63, 0x3e, 0x35, 0x69, - 0xfe, 0xd4, 0xa4, 0x3d, 0xb0, 0xd8, 0x9e, 0x7b, 0xc0, 0x5c, 0xdd, 0xea, 0xfa, 0xe7, 0xb0, 0x9b, - 0xc0, 0xc2, 0x29, 0x6c, 0xf4, 0x09, 0xd4, 0x4c, 0xf2, 0xe4, 0xa0, 0xe7, 0x76, 0xf3, 0xfc, 0x55, - 0x4e, 0x8f, 0xb8, 0x3f, 0x76, 0x25, 0x0a, 0x0e, 0xf1, 0xd4, 0x3f, 0x29, 0xb0, 0x96, 0xd8, 0x25, - 0xaf, 0x15, 0xf4, 0x71, 0xcf, 0x38, 0xa0, 0xd1, 0x89, 0xbf, 0x09, 0x33, 0x0e, 0x71, 0x99, 0x1e, - 0xd6, 0x8b, 0x6a, 0x6b, 0x6e, 0x34, 0x5c, 0x9d, 0xd9, 0x0f, 0x16, 0x71, 0x44, 0xcf, 0xf1, 0x4d, - 0xe5, 0xc5, 0xf9, 0x46, 0xfd, 0x8f, 0x02, 0xd5, 0x83, 0x36, 0x31, 0xe8, 0x05, 0x4c, 0x2a, 0xdb, - 0x89, 0x49, 0x45, 0x2d, 0x8c, 0x59, 0x61, 0x4f, 0xe1, 0x90, 0xb2, 0x93, 0x1a, 0x52, 0xae, 0x9d, - 0x83, 0x73, 0xf6, 0x7c, 0xf2, 0x3e, 0xcc, 0x84, 0xea, 0x12, 0x45, 0x59, 0x39, 0xaf, 0x28, 0xab, - 0xbf, 0xae, 0xc0, 0x6c, 0x4c, 0xc5, 0x78, 0xd2, 0xdc, 0xdd, 0xb1, 0xbe, 0x86, 0x17, 0xae, 0x8d, - 0x32, 0x1b, 0xd1, 0x82, 0x1e, 0xc6, 0x6f, 0x17, 0xa3, 0x66, 0x21, 0xdb, 0xda, 0xdc, 0x85, 0x3a, - 0x23, 0x6e, 0x97, 0xb2, 0x80, 0x26, 0x1c, 0x36, 0x13, 0xcd, 0x2a, 0x87, 0x09, 0x2a, 0x4e, 0x71, - 0x2f, 0xdf, 0x81, 0xb9, 0x84, 0xb2, 0xb1, 0x7a, 0xbe, 0x2f, 0xb8, 0x73, 0xa2, 0x54, 0xb8, 0x80, - 0xe8, 0xfa, 0x30, 0x11, 0x5d, 0xeb, 0xc5, 0xce, 0x8c, 0x25, 0x68, 0x51, 0x8c, 0xe1, 0x54, 0x8c, - 0xbd, 0x51, 0x0a, 0xed, 0xec, 0x48, 0xfb, 0x67, 0x05, 0x16, 0x63, 0xdc, 0xd1, 0x28, 0xfc, 0xbd, - 0xc4, 0x7d, 0xb0, 0x9e, 0xba, 0x0f, 0x1a, 0x79, 0x32, 0x2f, 0x6c, 0x16, 0xce, 0x9f, 0x4f, 0x27, - 0xfe, 0x1f, 0xe7, 0xd3, 0x3f, 0x28, 0x30, 0x1f, 0xf3, 0xdd, 0x05, 0x0c, 0xa8, 0x0f, 0x92, 0x03, - 0xea, 0xb5, 0x32, 0x41, 0x53, 0x30, 0xa1, 0xde, 0x86, 0x85, 0x18, 0xd3, 0x9e, 0xdb, 0xd1, 0x2d, - 0x62, 0x78, 0xe8, 0x55, 0xa8, 0x7a, 0x8c, 0xb8, 0x2c, 0xb8, 0x44, 0x02, 0xd9, 0x03, 0xbe, 0x88, - 0x7d, 0x9a, 0xfa, 0x2f, 0x05, 0x9a, 0x31, 0xe1, 0x7d, 0xea, 0x7a, 0xba, 0xc7, 0xa8, 0xc5, 0x1e, - 0xda, 0x46, 0xcf, 0xa4, 0x5b, 0x06, 0xd1, 0x4d, 0x4c, 0xf9, 0x82, 0x6e, 0x5b, 0xfb, 0xb6, 0xa1, - 0xb7, 0x07, 0x88, 0xc0, 0xec, 0xe7, 0x27, 0xd4, 0xda, 0xa6, 0x06, 0x65, 0xb4, 0x23, 0x43, 0xf1, - 0x07, 0x12, 0x7e, 0xf6, 0x51, 0x44, 0x7a, 0x3e, 0x5c, 0x5d, 0x2f, 0x83, 0x28, 0x22, 0x34, 0x8e, - 0x89, 0x7e, 0x06, 0xc0, 0x3f, 0x45, 0x2d, 0xeb, 0xc8, 0x60, 0xbd, 0x1b, 0x64, 0xf4, 0xa3, 0x90, - 0x32, 0x96, 0x82, 0x18, 0xa2, 0xfa, 0xdb, 0x5a, 0xe2, 0xbc, 0xbf, 0xf1, 0x63, 0xe6, 0xcf, 0x61, - 0xb1, 0x1f, 0x79, 0x27, 0x60, 0xe0, 0x6d, 0xf9, 0x44, 0xfa, 0xe9, 0x2e, 0x84, 0xcf, 0xf3, 0x6b, - 0xeb, 0xdb, 0x52, 0xc9, 0xe2, 0xc3, 0x1c, 0x38, 0x9c, 0xab, 0x04, 0x7d, 0x17, 0x66, 0xf9, 0x48, - 0xa3, 0xb7, 0xe9, 0x47, 0xc4, 0x0c, 0x72, 0x71, 0x21, 0x88, 0x97, 0x83, 0x88, 0x84, 0xe3, 0x7c, - 0xe8, 0x04, 0x16, 0x1c, 0xbb, 0xb3, 0x4b, 0x2c, 0xd2, 0xa5, 0xbc, 0x11, 0xf4, 0x8f, 0x52, 0xcc, - 0x9e, 0x33, 0xad, 0x77, 0x83, 0xf6, 0x7f, 0x3f, 0xcb, 0xf2, 0x9c, 0x0f, 0x71, 0xd9, 0x65, 0x11, - 0x04, 0x79, 0x90, 0xc8, 0x85, 0x7a, 0x4f, 0xf6, 0x63, 0x72, 0x14, 0xf7, 0x1f, 0xd9, 0x36, 0xca, - 0x24, 0xe5, 0x51, 0x42, 0x32, 0xba, 0x30, 0x93, 0xeb, 0x38, 0xa5, 0xa1, 0x70, 0xb4, 0xae, 0xfd, - 0x4f, 0xa3, 0x75, 0xce, 0xac, 0x3f, 0x33, 0xe6, 0xac, 0xff, 0x17, 0x05, 0xae, 0x39, 0x25, 0x72, - 0xa9, 0x01, 0xc2, 0x37, 0xf7, 0xcb, 0xf8, 0xa6, 0x4c, 0x6e, 0xb6, 0xd6, 0x47, 0xc3, 0xd5, 0x6b, - 0x65, 0x38, 0x71, 0x29, 0xfb, 0xd0, 0x43, 0xa8, 0xd9, 0xb2, 0x06, 0x36, 0x66, 0x85, 0xad, 0x37, - 0xca, 0xd8, 0x1a, 0xd4, 0x4d, 0x3f, 0x2d, 0x83, 0x2f, 0x1c, 0x62, 0xa9, 0xbf, 0xab, 0xc2, 0x95, - 0xcc, 0x0d, 0x8e, 0x7e, 0x78, 0xc6, 0x9c, 0x7f, 0xf5, 0x85, 0xcd, 0xf8, 0x99, 0x01, 0x7d, 0x62, - 0x8c, 0x01, 0x7d, 0x13, 0xe6, 0xdb, 0x3d, 0xd7, 0xa5, 0x16, 0x4b, 0x8d, 0xe7, 0x61, 0xb0, 0x6c, - 0x25, 0xc9, 0x38, 0xcd, 0x9f, 0xf7, 0xc6, 0x50, 0x1d, 0xf3, 0x8d, 0x21, 0x6e, 0x85, 0x9c, 0x13, - 0xfd, 0xd4, 0xce, 0x5a, 0x21, 0xc7, 0xc5, 0x34, 0x3f, 0x6f, 0x5a, 0x7d, 0xd4, 0x10, 0x61, 0x3a, - 0xd9, 0xb4, 0x1e, 0x25, 0xa8, 0x38, 0xc5, 0x9d, 0x33, 0xaf, 0xcf, 0x94, 0x9d, 0xd7, 0x11, 0x49, - 0xbc, 0x26, 0x80, 0xa8, 0xa3, 0x37, 0xcb, 0xc4, 0x59, 0xf9, 0xe7, 0x84, 0xdc, 0x87, 0x94, 0xd9, - 0xf1, 0x1f, 0x52, 0xd4, 0xbf, 0x2a, 0xf0, 0x72, 0x61, 0xc5, 0x42, 0x9b, 0x89, 0x96, 0xf2, 0x66, - 0xaa, 0xa5, 0xfc, 0x4e, 0xa1, 0x60, 0xac, 0xaf, 0x74, 0xf3, 0x5f, 0x1a, 0xde, 0x2f, 0xf7, 0xd2, - 0x90, 0x33, 0x05, 0x9f, 0xff, 0xe4, 0xd0, 0xfa, 0xfe, 0xd3, 0x67, 0x2b, 0x97, 0xbe, 0x7c, 0xb6, - 0x72, 0xe9, 0xab, 0x67, 0x2b, 0x97, 0x7e, 0x31, 0x5a, 0x51, 0x9e, 0x8e, 0x56, 0x94, 0x2f, 0x47, - 0x2b, 0xca, 0x57, 0xa3, 0x15, 0xe5, 0xef, 0xa3, 0x15, 0xe5, 0x57, 0x5f, 0xaf, 0x5c, 0xfa, 0x64, - 0xa9, 0xe0, 0xdf, 0xe8, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0xb9, 0xc9, 0xe6, 0x8c, 0xa7, 0x1e, - 0x00, 0x00, + // 2041 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x59, 0xdd, 0x6f, 0x1b, 0xc7, + 0x11, 0xd7, 0x51, 0xa2, 0x44, 0x8d, 0x22, 0xca, 0x5e, 0xa9, 0x16, 0xa3, 0xb4, 0x92, 0x70, 0x31, + 0x62, 0x25, 0xb1, 0x8f, 0xb1, 0x92, 0x06, 0x89, 0xdd, 0xba, 0x10, 0x25, 0x37, 0x56, 0x20, 0x45, + 0xca, 0x4a, 0xb2, 0xd1, 0xf4, 0x03, 0x59, 0x91, 0x6b, 0xea, 0xa2, 0xfb, 0xc2, 0xdd, 0x52, 0x31, + 0xd1, 0x97, 0xfe, 0x01, 0x2d, 0xd2, 0xe7, 0xfe, 0x15, 0xed, 0x53, 0x8b, 0x16, 0x7d, 0x2d, 0xfc, + 0x18, 0xf4, 0xa5, 0x79, 0x22, 0x6a, 0xe6, 0xb5, 0x7d, 0x6b, 0x5f, 0x0c, 0x14, 0x28, 0x76, 0x6f, + 0xef, 0xfb, 0x4e, 0x3a, 0x16, 0xb0, 0x80, 0xe6, 0x8d, 0xb7, 0x33, 0xf3, 0x9b, 0xd9, 0xd9, 0x99, + 0xd9, 0x99, 0x25, 0xdc, 0x38, 0x7d, 0xcf, 0xd3, 0x74, 0xbb, 0x49, 0x1c, 0xbd, 0x49, 0x1c, 0xc7, + 0x6b, 0x9e, 0xdd, 0x3e, 0xa6, 0x8c, 0xdc, 0x6e, 0x76, 0xa9, 0x45, 0x5d, 0xc2, 0x68, 0x47, 0x73, + 0x5c, 0x9b, 0xd9, 0x68, 0xd1, 0x67, 0xd4, 0x88, 0xa3, 0x6b, 0x9c, 0x51, 0x93, 0x8c, 0x4b, 0xb7, + 0xba, 0x3a, 0x3b, 0xe9, 0x1d, 0x6b, 0x6d, 0xdb, 0x6c, 0x76, 0xed, 0xae, 0xdd, 0x14, 0xfc, 0xc7, + 0xbd, 0xc7, 0xe2, 0x4b, 0x7c, 0x88, 0x5f, 0x3e, 0xce, 0x92, 0x1a, 0x53, 0xd8, 0xb6, 0x5d, 0xda, + 0x3c, 0xcb, 0xe8, 0x5a, 0x7a, 0x27, 0xe2, 0x31, 0x49, 0xfb, 0x44, 0xb7, 0xa8, 0xdb, 0x6f, 0x3a, + 0xa7, 0x5d, 0xbe, 0xe0, 0x35, 0x4d, 0xca, 0x48, 0x9e, 0x54, 0xb3, 0x48, 0xca, 0xed, 0x59, 0x4c, + 0x37, 0x69, 0x46, 0xe0, 0xdd, 0x8b, 0x04, 0xbc, 0xf6, 0x09, 0x35, 0x49, 0x46, 0xee, 0xed, 0x22, + 0xb9, 0x1e, 0xd3, 0x8d, 0xa6, 0x6e, 0x31, 0x8f, 0xb9, 0x69, 0x21, 0xf5, 0xdf, 0x0a, 0xa0, 0x4d, + 0xdb, 0x62, 0xae, 0x6d, 0x18, 0xd4, 0xc5, 0xf4, 0x4c, 0xf7, 0x74, 0xdb, 0x42, 0x9f, 0x42, 0x8d, + 0xef, 0xa7, 0x43, 0x18, 0x69, 0x28, 0xab, 0xca, 0xda, 0xcc, 0xfa, 0x5b, 0x5a, 0xe4, 0xe9, 0x10, + 0x5e, 0x73, 0x4e, 0xbb, 0x7c, 0xc1, 0xd3, 0x38, 0xb7, 0x76, 0x76, 0x5b, 0xdb, 0x3b, 0xfe, 0x8c, + 0xb6, 0xd9, 0x2e, 0x65, 0xa4, 0x85, 0x9e, 0x0e, 0x56, 0xc6, 0x86, 0x83, 0x15, 0x88, 0xd6, 0x70, + 0x88, 0x8a, 0xf6, 0x60, 0x42, 0xa0, 0x57, 0x04, 0xfa, 0xad, 0x42, 0x74, 0xb9, 0x69, 0x0d, 0x93, + 0xcf, 0xef, 0x3f, 0x61, 0xd4, 0xe2, 0xe6, 0xb5, 0x5e, 0x92, 0xd0, 0x13, 0x5b, 0x84, 0x11, 0x2c, + 0x80, 0xd0, 0x4d, 0xa8, 0xb9, 0xd2, 0xfc, 0xc6, 0xf8, 0xaa, 0xb2, 0x36, 0xde, 0xba, 0x22, 0xb9, + 0x6a, 0xc1, 0xb6, 0x70, 0xc8, 0xa1, 0x3e, 0x55, 0xe0, 0x5a, 0x76, 0xdf, 0x3b, 0xba, 0xc7, 0xd0, + 0x4f, 0x32, 0x7b, 0xd7, 0xca, 0xed, 0x9d, 0x4b, 0x8b, 0x9d, 0x87, 0x8a, 0x83, 0x95, 0xd8, 0xbe, + 0xf7, 0xa1, 0xaa, 0x33, 0x6a, 0x7a, 0x8d, 0xca, 0xea, 0xf8, 0xda, 0xcc, 0xfa, 0x9b, 0x5a, 0x41, + 0x00, 0x6b, 0x59, 0xeb, 0x5a, 0xb3, 0x12, 0xb7, 0xba, 0xcd, 0x11, 0xb0, 0x0f, 0xa4, 0xfe, 0xb2, + 0x02, 0xb0, 0x45, 0x1d, 0xc3, 0xee, 0x9b, 0xd4, 0x62, 0x97, 0x70, 0x74, 0xdb, 0x30, 0xe1, 0x39, + 0xb4, 0x2d, 0x8f, 0xee, 0x46, 0xe1, 0x0e, 0x22, 0xa3, 0x0e, 0x1c, 0xda, 0x8e, 0x0e, 0x8d, 0x7f, + 0x61, 0x01, 0x81, 0x3e, 0x86, 0x49, 0x8f, 0x11, 0xd6, 0xf3, 0xc4, 0x91, 0xcd, 0xac, 0xbf, 0x5e, + 0x06, 0x4c, 0x08, 0xb4, 0xea, 0x12, 0x6e, 0xd2, 0xff, 0xc6, 0x12, 0x48, 0xfd, 0xdb, 0x38, 0xcc, + 0x47, 0xcc, 0x9b, 0xb6, 0xd5, 0xd1, 0x19, 0x0f, 0xe9, 0xbb, 0x30, 0xc1, 0xfa, 0x0e, 0x15, 0x3e, + 0x99, 0x6e, 0xdd, 0x08, 0x8c, 0x39, 0xec, 0x3b, 0xf4, 0xf9, 0x60, 0x65, 0x31, 0x47, 0x84, 0x93, + 0xb0, 0x10, 0x42, 0x3b, 0xa1, 0x9d, 0x15, 0x21, 0xfe, 0x4e, 0x52, 0xf9, 0xf3, 0xc1, 0x4a, 0x4e, + 0x01, 0xd1, 0x42, 0xa4, 0xa4, 0x89, 0xe8, 0x33, 0xa8, 0x1b, 0xc4, 0x63, 0x47, 0x4e, 0x87, 0x30, + 0x7a, 0xa8, 0x9b, 0xb4, 0x31, 0x29, 0x76, 0xff, 0x46, 0xb9, 0x83, 0xe2, 0x12, 0xad, 0x6b, 0xd2, + 0x82, 0xfa, 0x4e, 0x02, 0x09, 0xa7, 0x90, 0xd1, 0x19, 0x20, 0xbe, 0x72, 0xe8, 0x12, 0xcb, 0xf3, + 0x77, 0xc5, 0xf5, 0x4d, 0x8d, 0xac, 0x6f, 0x49, 0xea, 0x43, 0x3b, 0x19, 0x34, 0x9c, 0xa3, 0x01, + 0xbd, 0x06, 0x93, 0x2e, 0x25, 0x9e, 0x6d, 0x35, 0x26, 0x84, 0xc7, 0xc2, 0xe3, 0xc2, 0x62, 0x15, + 0x4b, 0x2a, 0x7a, 0x1d, 0xa6, 0x4c, 0xea, 0x79, 0xa4, 0x4b, 0x1b, 0x55, 0xc1, 0x38, 0x27, 0x19, + 0xa7, 0x76, 0xfd, 0x65, 0x1c, 0xd0, 0xd5, 0x3f, 0x28, 0x50, 0x8f, 0x8e, 0xe9, 0x12, 0x72, 0xf5, + 0x41, 0x32, 0x57, 0x5f, 0x2d, 0x11, 0x9c, 0x05, 0x39, 0xfa, 0x8f, 0x0a, 0xa0, 0x88, 0x09, 0xdb, + 0x86, 0x71, 0x4c, 0xda, 0xa7, 0x68, 0x15, 0x26, 0x2c, 0x62, 0x06, 0x31, 0x19, 0x26, 0xc8, 0x47, + 0xc4, 0xa4, 0x58, 0x50, 0xd0, 0x17, 0x0a, 0xa0, 0x9e, 0x38, 0xcd, 0xce, 0x86, 0x65, 0xd9, 0x8c, + 0x70, 0x07, 0x07, 0x06, 0x6d, 0x96, 0x30, 0x28, 0xd0, 0xa5, 0x1d, 0x65, 0x50, 0xee, 0x5b, 0xcc, + 0xed, 0x47, 0x07, 0x9b, 0x65, 0xc0, 0x39, 0xaa, 0xd1, 0x8f, 0x01, 0x5c, 0x89, 0x79, 0x68, 0xcb, + 0xb4, 0x2d, 0xae, 0x01, 0x81, 0xfa, 0x4d, 0xdb, 0x7a, 0xac, 0x77, 0xa3, 0xc2, 0x82, 0x43, 0x08, + 0x1c, 0x83, 0x5b, 0xba, 0x0f, 0x8b, 0x05, 0x76, 0xa2, 0x2b, 0x30, 0x7e, 0x4a, 0xfb, 0xbe, 0xab, + 0x30, 0xff, 0x89, 0x16, 0xa0, 0x7a, 0x46, 0x8c, 0x1e, 0xf5, 0x73, 0x12, 0xfb, 0x1f, 0x77, 0x2a, + 0xef, 0x29, 0xea, 0x6f, 0xab, 0xf1, 0x48, 0xe1, 0xf5, 0x06, 0xad, 0xf1, 0xeb, 0xc1, 0x31, 0xf4, + 0x36, 0xf1, 0x04, 0x46, 0xb5, 0xf5, 0x92, 0x7f, 0x35, 0xf8, 0x6b, 0x38, 0xa4, 0xa2, 0x9f, 0x42, + 0xcd, 0xa3, 0x06, 0x6d, 0x33, 0xdb, 0x95, 0x25, 0xee, 0xed, 0x92, 0x31, 0x45, 0x8e, 0xa9, 0x71, + 0x20, 0x45, 0x7d, 0xf8, 0xe0, 0x0b, 0x87, 0x90, 0xe8, 0x63, 0xa8, 0x31, 0x6a, 0x3a, 0x06, 0x61, + 0x54, 0x7a, 0x2f, 0x11, 0x57, 0xbc, 0x76, 0x70, 0xb0, 0x7d, 0xbb, 0x73, 0x28, 0xd9, 0x44, 0xf5, + 0x0c, 0xe3, 0x34, 0x58, 0xc5, 0x21, 0x0c, 0xfa, 0x11, 0xd4, 0x3c, 0xc6, 0x6f, 0xf5, 0x6e, 0x5f, + 0x64, 0xdb, 0x79, 0xd7, 0x4a, 0xbc, 0x8e, 0xfa, 0x22, 0x11, 0x74, 0xb0, 0x82, 0x43, 0x38, 0xb4, + 0x01, 0x73, 0xa6, 0x6e, 0x61, 0x4a, 0x3a, 0xfd, 0x03, 0xda, 0xb6, 0xad, 0x8e, 0x27, 0xd2, 0xb4, + 0xda, 0x5a, 0x94, 0x42, 0x73, 0xbb, 0x49, 0x32, 0x4e, 0xf3, 0xa3, 0x1d, 0x58, 0x08, 0xae, 0xdd, + 0x07, 0xba, 0xc7, 0x6c, 0xb7, 0xbf, 0xa3, 0x9b, 0x3a, 0x13, 0x35, 0xaf, 0xda, 0x6a, 0x0c, 0x07, + 0x2b, 0x0b, 0x38, 0x87, 0x8e, 0x73, 0xa5, 0x78, 0x5d, 0x71, 0x48, 0xcf, 0xa3, 0x1d, 0x51, 0xc3, + 0x6a, 0x51, 0x5d, 0xd9, 0x17, 0xab, 0x58, 0x52, 0xd1, 0xa3, 0x44, 0x98, 0xd6, 0x46, 0x0b, 0xd3, + 0x7a, 0x71, 0x88, 0xa2, 0x23, 0x58, 0x74, 0x5c, 0xbb, 0xeb, 0x52, 0xcf, 0xdb, 0xa2, 0xa4, 0x63, + 0xe8, 0x16, 0x0d, 0x3c, 0x33, 0x2d, 0x76, 0xf4, 0xca, 0x70, 0xb0, 0xb2, 0xb8, 0x9f, 0xcf, 0x82, + 0x8b, 0x64, 0xd5, 0x5f, 0x55, 0xe1, 0x4a, 0xfa, 0x8e, 0x43, 0x1f, 0x02, 0xb2, 0x8f, 0x3d, 0xea, + 0x9e, 0xd1, 0xce, 0x07, 0x7e, 0xe3, 0xc6, 0xbb, 0x1b, 0x45, 0x74, 0x37, 0x61, 0xde, 0xee, 0x65, + 0x38, 0x70, 0x8e, 0x94, 0xdf, 0x1f, 0xc9, 0x04, 0xa8, 0x08, 0x43, 0x63, 0xfd, 0x51, 0x26, 0x09, + 0x36, 0x60, 0x4e, 0xe6, 0x7e, 0x40, 0x14, 0xc1, 0x1a, 0x3b, 0xf7, 0xa3, 0x24, 0x19, 0xa7, 0xf9, + 0xd1, 0x5d, 0x98, 0x75, 0x79, 0x1c, 0x84, 0x00, 0x53, 0x02, 0xe0, 0x5b, 0x12, 0x60, 0x16, 0xc7, + 0x89, 0x38, 0xc9, 0x8b, 0x3e, 0x80, 0xab, 0xe4, 0x8c, 0xe8, 0x06, 0x39, 0x36, 0x68, 0x08, 0x30, + 0x21, 0x00, 0x5e, 0x96, 0x00, 0x57, 0x37, 0xd2, 0x0c, 0x38, 0x2b, 0x83, 0x76, 0x61, 0xbe, 0x67, + 0x65, 0xa1, 0xfc, 0x20, 0x7e, 0x45, 0x42, 0xcd, 0x1f, 0x65, 0x59, 0x70, 0x9e, 0x1c, 0xda, 0x86, + 0x79, 0x46, 0x5d, 0x53, 0xb7, 0x08, 0xd3, 0xad, 0x6e, 0x08, 0xe7, 0x9f, 0xfc, 0x22, 0x87, 0x3a, + 0xcc, 0x92, 0x71, 0x9e, 0x0c, 0xfa, 0x14, 0xa0, 0x1d, 0x34, 0x08, 0x5e, 0x63, 0x52, 0x54, 0xf4, + 0x9b, 0x25, 0xf2, 0x36, 0xec, 0x2a, 0xa2, 0x6a, 0x1a, 0x2e, 0x79, 0x38, 0x86, 0x89, 0xee, 0x40, + 0xbd, 0x6d, 0x1b, 0x86, 0x48, 0xa2, 0x4d, 0xbb, 0x67, 0x31, 0x91, 0x07, 0xd5, 0x16, 0xe2, 0x7d, + 0xc3, 0x66, 0x82, 0x82, 0x53, 0x9c, 0xea, 0x9f, 0x94, 0xf8, 0x8d, 0x15, 0x54, 0x06, 0x74, 0x27, + 0xd1, 0x45, 0xbd, 0x96, 0xea, 0xa2, 0xae, 0x65, 0x25, 0x62, 0x4d, 0x94, 0x0e, 0xb3, 0x3c, 0x8f, + 0x74, 0xab, 0xeb, 0xc7, 0x8e, 0xac, 0xae, 0x6f, 0x9d, 0x9b, 0x95, 0x21, 0x77, 0xec, 0x8e, 0xbd, + 0x2a, 0xc2, 0x27, 0x4e, 0xc4, 0x49, 0x64, 0xf5, 0x1e, 0xd4, 0x93, 0x29, 0x9d, 0x18, 0x0f, 0x94, + 0x0b, 0xc7, 0x83, 0xaf, 0x15, 0x58, 0x2c, 0xd0, 0x8e, 0x0c, 0xa8, 0x9b, 0xe4, 0x49, 0x2c, 0x62, + 0x2e, 0x6c, 0xb3, 0xf9, 0x00, 0xa6, 0xf9, 0x03, 0x98, 0xb6, 0x6d, 0xb1, 0x3d, 0xf7, 0x80, 0xb9, + 0xba, 0xd5, 0xf5, 0xcf, 0x61, 0x37, 0x81, 0x85, 0x53, 0xd8, 0xe8, 0x13, 0xa8, 0x99, 0xe4, 0xc9, + 0x41, 0xcf, 0xed, 0xe6, 0xf9, 0xab, 0x9c, 0x1e, 0x71, 0x15, 0xed, 0x4a, 0x14, 0x1c, 0xe2, 0xa9, + 0x7f, 0x56, 0x60, 0x35, 0xb1, 0x4b, 0x5e, 0x76, 0xe8, 0xe3, 0x9e, 0x71, 0x40, 0xa3, 0x13, 0x7f, + 0x13, 0xa6, 0x1d, 0xe2, 0x32, 0x3d, 0x2c, 0x3d, 0xd5, 0xd6, 0xec, 0x70, 0xb0, 0x32, 0xbd, 0x1f, + 0x2c, 0xe2, 0x88, 0x9e, 0xe3, 0x9b, 0xca, 0x8b, 0xf3, 0x8d, 0xfa, 0x1f, 0x05, 0xaa, 0x07, 0x6d, + 0x62, 0xd0, 0x4b, 0x18, 0x7a, 0xb6, 0x12, 0x43, 0x8f, 0x5a, 0x18, 0xb3, 0xc2, 0x9e, 0xc2, 0x79, + 0x67, 0x27, 0x35, 0xef, 0x5c, 0xbf, 0x00, 0xe7, 0xfc, 0x51, 0xe7, 0x7d, 0x98, 0x0e, 0xd5, 0x25, + 0xea, 0xbb, 0x72, 0x51, 0x7d, 0x57, 0x7f, 0x53, 0x81, 0x99, 0x98, 0x8a, 0xd1, 0xa4, 0xb9, 0xbb, + 0x63, 0x2d, 0x12, 0x2f, 0x5c, 0xeb, 0x65, 0x36, 0xa2, 0x05, 0xed, 0x90, 0xdf, 0x79, 0x46, 0x7d, + 0x47, 0xb6, 0x4b, 0xba, 0x07, 0x75, 0x46, 0xdc, 0x2e, 0x65, 0x01, 0x4d, 0x38, 0x6c, 0x3a, 0x1a, + 0x7b, 0x0e, 0x13, 0x54, 0x9c, 0xe2, 0x5e, 0xba, 0x0b, 0xb3, 0x09, 0x65, 0x23, 0xb5, 0x8f, 0x5f, + 0x70, 0xe7, 0x44, 0xa9, 0x70, 0x09, 0xd1, 0xf5, 0x61, 0x22, 0xba, 0xd6, 0x8a, 0x9d, 0x19, 0x4b, + 0xd0, 0xa2, 0x18, 0xc3, 0xa9, 0x18, 0x7b, 0xa3, 0x14, 0xda, 0xf9, 0x91, 0xf6, 0xcf, 0x0a, 0x2c, + 0xc4, 0xb8, 0xa3, 0xa9, 0xfa, 0x7b, 0x89, 0xfb, 0x60, 0x2d, 0x75, 0x1f, 0x34, 0xf2, 0x64, 0x5e, + 0xd8, 0x58, 0x9d, 0x3f, 0xea, 0x8e, 0xff, 0x3f, 0x8e, 0xba, 0x7f, 0x54, 0x60, 0x2e, 0xe6, 0xbb, + 0x4b, 0x98, 0x75, 0xb7, 0x93, 0xb3, 0xee, 0xf5, 0x32, 0x41, 0x53, 0x30, 0xec, 0xde, 0x81, 0xf9, + 0x18, 0xd3, 0x9e, 0xdb, 0xd1, 0x2d, 0x62, 0x78, 0xe8, 0x55, 0xa8, 0x7a, 0x8c, 0xb8, 0x2c, 0xb8, + 0x44, 0x02, 0xd9, 0x03, 0xbe, 0x88, 0x7d, 0x9a, 0xfa, 0x2f, 0x05, 0x9a, 0x31, 0xe1, 0x7d, 0xea, + 0x7a, 0xba, 0xc7, 0xa8, 0xc5, 0x1e, 0xda, 0x46, 0xcf, 0xa4, 0x9b, 0x06, 0xd1, 0x4d, 0x4c, 0xf9, + 0x82, 0x6e, 0x5b, 0xfb, 0xb6, 0xa1, 0xb7, 0xfb, 0x88, 0xc0, 0xcc, 0xe7, 0x27, 0xd4, 0xda, 0xa2, + 0x06, 0x65, 0xb4, 0x23, 0x43, 0xf1, 0x07, 0x12, 0x7e, 0xe6, 0x51, 0x44, 0x7a, 0x3e, 0x58, 0x59, + 0x2b, 0x83, 0x28, 0x22, 0x34, 0x8e, 0x89, 0x7e, 0x06, 0xc0, 0x3f, 0x45, 0x2d, 0xeb, 0xc8, 0x60, + 0xbd, 0x17, 0x64, 0xf4, 0xa3, 0x90, 0x32, 0x92, 0x82, 0x18, 0xa2, 0xfa, 0xbb, 0x5a, 0xe2, 0xbc, + 0xbf, 0xf1, 0x13, 0xeb, 0xcf, 0x61, 0xe1, 0x2c, 0xf2, 0x4e, 0xc0, 0xc0, 0x3b, 0xfc, 0xf1, 0xf4, + 0x2b, 0x60, 0x08, 0x9f, 0xe7, 0xd7, 0xd6, 0xb7, 0xa5, 0x92, 0x85, 0x87, 0x39, 0x70, 0x38, 0x57, + 0x09, 0xfa, 0x2e, 0xcc, 0xf0, 0xe9, 0x48, 0x6f, 0xd3, 0x8f, 0x88, 0x19, 0xe4, 0xe2, 0x7c, 0x10, + 0x2f, 0x07, 0x11, 0x09, 0xc7, 0xf9, 0xd0, 0x09, 0xcc, 0x3b, 0x76, 0x67, 0x97, 0x58, 0xa4, 0x4b, + 0x79, 0x23, 0xe8, 0x1f, 0xa5, 0x18, 0x63, 0xa7, 0x5b, 0xef, 0x06, 0x93, 0xc4, 0x7e, 0x96, 0xe5, + 0x39, 0x9f, 0x07, 0xb3, 0xcb, 0x22, 0x08, 0xf2, 0x20, 0x91, 0x0b, 0xf5, 0x9e, 0xec, 0xc7, 0xe4, + 0x54, 0xef, 0xbf, 0xd7, 0xad, 0x97, 0x49, 0xca, 0xa3, 0x84, 0x64, 0x74, 0x61, 0x26, 0xd7, 0x71, + 0x4a, 0x43, 0xe1, 0x94, 0x5e, 0xfb, 0x9f, 0xa6, 0xf4, 0x9c, 0x67, 0x83, 0xe9, 0x11, 0x9f, 0x0d, + 0xfe, 0xa2, 0xc0, 0x75, 0xa7, 0x44, 0x2e, 0x35, 0x40, 0xf8, 0xe6, 0x41, 0x19, 0xdf, 0x94, 0xc9, + 0xcd, 0xd6, 0xda, 0x70, 0xb0, 0x72, 0xbd, 0x0c, 0x27, 0x2e, 0x65, 0x1f, 0x7a, 0x08, 0x35, 0x5b, + 0xd6, 0xc0, 0xc6, 0x8c, 0xb0, 0xf5, 0x66, 0x19, 0x5b, 0x83, 0xba, 0xe9, 0xa7, 0x65, 0xf0, 0x85, + 0x43, 0x2c, 0xf5, 0xf7, 0x55, 0xb8, 0x9a, 0xb9, 0xc1, 0xd1, 0x0f, 0xcf, 0x79, 0x32, 0xb8, 0xf6, + 0xc2, 0x9e, 0x0b, 0x32, 0xb3, 0xfe, 0xf8, 0x08, 0xb3, 0xfe, 0x06, 0xcc, 0xb5, 0x7b, 0xae, 0x4b, + 0x2d, 0x96, 0x9a, 0xf4, 0xc3, 0x60, 0xd9, 0x4c, 0x92, 0x71, 0x9a, 0x3f, 0xef, 0xb9, 0xa2, 0x3a, + 0xe2, 0x73, 0x45, 0xdc, 0x0a, 0x39, 0x27, 0xfa, 0xa9, 0x9d, 0xb5, 0x42, 0x8e, 0x8b, 0x69, 0x7e, + 0xde, 0xb4, 0xfa, 0xa8, 0x21, 0xc2, 0x54, 0xb2, 0x69, 0x3d, 0x4a, 0x50, 0x71, 0x8a, 0x3b, 0x67, + 0x5e, 0x9f, 0x2e, 0x3b, 0xaf, 0x23, 0x92, 0x78, 0x4d, 0x00, 0x51, 0x47, 0x6f, 0x95, 0x89, 0xb3, + 0xf2, 0xcf, 0x09, 0xb9, 0x6f, 0x32, 0x33, 0xa3, 0xbf, 0xc9, 0xa8, 0x7f, 0x55, 0xe0, 0xe5, 0xc2, + 0x8a, 0x85, 0x36, 0x12, 0x2d, 0xe5, 0xad, 0x54, 0x4b, 0xf9, 0x9d, 0x42, 0xc1, 0x58, 0x5f, 0xe9, + 0xe6, 0xbf, 0x34, 0xbc, 0x5f, 0xee, 0xa5, 0x21, 0x67, 0x0a, 0xbe, 0xf8, 0xc9, 0xa1, 0xf5, 0xfd, + 0xa7, 0xcf, 0x96, 0xc7, 0xbe, 0x7c, 0xb6, 0x3c, 0xf6, 0xd5, 0xb3, 0xe5, 0xb1, 0x5f, 0x0c, 0x97, + 0x95, 0xa7, 0xc3, 0x65, 0xe5, 0xcb, 0xe1, 0xb2, 0xf2, 0xd5, 0x70, 0x59, 0xf9, 0xfb, 0x70, 0x59, + 0xf9, 0xf5, 0xd7, 0xcb, 0x63, 0x9f, 0x2c, 0x16, 0xfc, 0xb1, 0xfd, 0xdf, 0x00, 0x00, 0x00, 0xff, + 0xff, 0x40, 0xa4, 0x4b, 0xb9, 0xf2, 0x1e, 0x00, 0x00, } func (m *ControllerRevision) Marshal() (dAtA []byte, err error) { @@ -1289,6 +1290,11 @@ func (m *DeploymentStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.TerminatingReplicas != nil { + i = encodeVarintGenerated(dAtA, i, uint64(*m.TerminatingReplicas)) + i-- + dAtA[i] = 0x48 + } if m.CollisionCount != nil { i = encodeVarintGenerated(dAtA, i, uint64(*m.CollisionCount)) i-- @@ -2225,6 +2231,9 @@ func (m *DeploymentStatus) Size() (n int) { if m.CollisionCount != nil { n += 1 + sovGenerated(uint64(*m.CollisionCount)) } + if m.TerminatingReplicas != nil { + n += 1 + sovGenerated(uint64(*m.TerminatingReplicas)) + } return n } @@ -2627,6 +2636,7 @@ func (this *DeploymentStatus) String() string { `Conditions:` + repeatedStringForConditions + `,`, `ReadyReplicas:` + fmt.Sprintf("%v", this.ReadyReplicas) + `,`, `CollisionCount:` + valueToStringGenerated(this.CollisionCount) + `,`, + `TerminatingReplicas:` + valueToStringGenerated(this.TerminatingReplicas) + `,`, `}`, }, "") return s @@ -4337,6 +4347,26 @@ func (m *DeploymentStatus) Unmarshal(dAtA []byte) error { } } m.CollisionCount = &v + case 9: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TerminatingReplicas", wireType) + } + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.TerminatingReplicas = &v default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/go-controller/vendor/k8s.io/api/apps/v1beta1/generated.proto b/go-controller/vendor/k8s.io/api/apps/v1beta1/generated.proto index 46d7bfdf92..0601efc3c4 100644 --- a/go-controller/vendor/k8s.io/api/apps/v1beta1/generated.proto +++ b/go-controller/vendor/k8s.io/api/apps/v1beta1/generated.proto @@ -179,33 +179,40 @@ message DeploymentSpec { // DeploymentStatus is the most recently observed status of the Deployment. message DeploymentStatus { - // observedGeneration is the generation observed by the deployment controller. + // The generation observed by the deployment controller. // +optional optional int64 observedGeneration = 1; - // replicas is the total number of non-terminated pods targeted by this deployment (their labels match the selector). + // Total number of non-terminating pods targeted by this deployment (their labels match the selector). // +optional optional int32 replicas = 2; - // updatedReplicas is the total number of non-terminated pods targeted by this deployment that have the desired template spec. + // Total number of non-terminating pods targeted by this deployment that have the desired template spec. // +optional optional int32 updatedReplicas = 3; - // readyReplicas is the number of pods targeted by this Deployment controller with a Ready Condition. + // Total number of non-terminating pods targeted by this Deployment with a Ready Condition. // +optional optional int32 readyReplicas = 7; - // Total number of available pods (ready for at least minReadySeconds) targeted by this deployment. + // Total number of available non-terminating pods (ready for at least minReadySeconds) targeted by this deployment. // +optional optional int32 availableReplicas = 4; - // unavailableReplicas is the total number of unavailable pods targeted by this deployment. This is the total number of + // Total number of unavailable pods targeted by this deployment. This is the total number of // pods that are still required for the deployment to have 100% available capacity. They may // either be pods that are running but not yet available or pods that still have not been created. // +optional optional int32 unavailableReplicas = 5; - // Conditions represent the latest available observations of a deployment's current state. + // Total number of terminating pods targeted by this deployment. Terminating pods have a non-null + // .metadata.deletionTimestamp and have not yet reached the Failed or Succeeded .status.phase. + // + // This is an alpha field. Enable DeploymentReplicaSetTerminatingReplicas to be able to use this field. + // +optional + optional int32 terminatingReplicas = 9; + + // Represents the latest available observations of a deployment's current state. // +patchMergeKey=type // +patchStrategy=merge // +listType=map @@ -455,6 +462,7 @@ message StatefulSetSpec { // the network identity of the set. Pods get DNS/hostnames that follow the // pattern: pod-specific-string.serviceName.default.svc.cluster.local // where "pod-specific-string" is managed by the StatefulSet controller. + // +optional optional string serviceName = 5; // podManagementPolicy controls how pods are created during initial scale up, diff --git a/go-controller/vendor/k8s.io/api/apps/v1beta1/types.go b/go-controller/vendor/k8s.io/api/apps/v1beta1/types.go index bc48519578..5530c990da 100644 --- a/go-controller/vendor/k8s.io/api/apps/v1beta1/types.go +++ b/go-controller/vendor/k8s.io/api/apps/v1beta1/types.go @@ -259,6 +259,7 @@ type StatefulSetSpec struct { // the network identity of the set. Pods get DNS/hostnames that follow the // pattern: pod-specific-string.serviceName.default.svc.cluster.local // where "pod-specific-string" is managed by the StatefulSet controller. + // +optional ServiceName string `json:"serviceName" protobuf:"bytes,5,opt,name=serviceName"` // podManagementPolicy controls how pods are created during initial scale up, @@ -548,33 +549,40 @@ type RollingUpdateDeployment struct { // DeploymentStatus is the most recently observed status of the Deployment. type DeploymentStatus struct { - // observedGeneration is the generation observed by the deployment controller. + // The generation observed by the deployment controller. // +optional ObservedGeneration int64 `json:"observedGeneration,omitempty" protobuf:"varint,1,opt,name=observedGeneration"` - // replicas is the total number of non-terminated pods targeted by this deployment (their labels match the selector). + // Total number of non-terminating pods targeted by this deployment (their labels match the selector). // +optional Replicas int32 `json:"replicas,omitempty" protobuf:"varint,2,opt,name=replicas"` - // updatedReplicas is the total number of non-terminated pods targeted by this deployment that have the desired template spec. + // Total number of non-terminating pods targeted by this deployment that have the desired template spec. // +optional UpdatedReplicas int32 `json:"updatedReplicas,omitempty" protobuf:"varint,3,opt,name=updatedReplicas"` - // readyReplicas is the number of pods targeted by this Deployment controller with a Ready Condition. + // Total number of non-terminating pods targeted by this Deployment with a Ready Condition. // +optional ReadyReplicas int32 `json:"readyReplicas,omitempty" protobuf:"varint,7,opt,name=readyReplicas"` - // Total number of available pods (ready for at least minReadySeconds) targeted by this deployment. + // Total number of available non-terminating pods (ready for at least minReadySeconds) targeted by this deployment. // +optional AvailableReplicas int32 `json:"availableReplicas,omitempty" protobuf:"varint,4,opt,name=availableReplicas"` - // unavailableReplicas is the total number of unavailable pods targeted by this deployment. This is the total number of + // Total number of unavailable pods targeted by this deployment. This is the total number of // pods that are still required for the deployment to have 100% available capacity. They may // either be pods that are running but not yet available or pods that still have not been created. // +optional UnavailableReplicas int32 `json:"unavailableReplicas,omitempty" protobuf:"varint,5,opt,name=unavailableReplicas"` - // Conditions represent the latest available observations of a deployment's current state. + // Total number of terminating pods targeted by this deployment. Terminating pods have a non-null + // .metadata.deletionTimestamp and have not yet reached the Failed or Succeeded .status.phase. + // + // This is an alpha field. Enable DeploymentReplicaSetTerminatingReplicas to be able to use this field. + // +optional + TerminatingReplicas *int32 `json:"terminatingReplicas,omitempty" protobuf:"varint,9,opt,name=terminatingReplicas"` + + // Represents the latest available observations of a deployment's current state. // +patchMergeKey=type // +patchStrategy=merge // +listType=map diff --git a/go-controller/vendor/k8s.io/api/apps/v1beta1/types_swagger_doc_generated.go b/go-controller/vendor/k8s.io/api/apps/v1beta1/types_swagger_doc_generated.go index 1381d75dc0..02ea5f7f26 100644 --- a/go-controller/vendor/k8s.io/api/apps/v1beta1/types_swagger_doc_generated.go +++ b/go-controller/vendor/k8s.io/api/apps/v1beta1/types_swagger_doc_generated.go @@ -113,13 +113,14 @@ func (DeploymentSpec) SwaggerDoc() map[string]string { var map_DeploymentStatus = map[string]string{ "": "DeploymentStatus is the most recently observed status of the Deployment.", - "observedGeneration": "observedGeneration is the generation observed by the deployment controller.", - "replicas": "replicas is the total number of non-terminated pods targeted by this deployment (their labels match the selector).", - "updatedReplicas": "updatedReplicas is the total number of non-terminated pods targeted by this deployment that have the desired template spec.", - "readyReplicas": "readyReplicas is the number of pods targeted by this Deployment controller with a Ready Condition.", - "availableReplicas": "Total number of available pods (ready for at least minReadySeconds) targeted by this deployment.", - "unavailableReplicas": "unavailableReplicas is the total number of unavailable pods targeted by this deployment. This is the total number of pods that are still required for the deployment to have 100% available capacity. They may either be pods that are running but not yet available or pods that still have not been created.", - "conditions": "Conditions represent the latest available observations of a deployment's current state.", + "observedGeneration": "The generation observed by the deployment controller.", + "replicas": "Total number of non-terminating pods targeted by this deployment (their labels match the selector).", + "updatedReplicas": "Total number of non-terminating pods targeted by this deployment that have the desired template spec.", + "readyReplicas": "Total number of non-terminating pods targeted by this Deployment with a Ready Condition.", + "availableReplicas": "Total number of available non-terminating pods (ready for at least minReadySeconds) targeted by this deployment.", + "unavailableReplicas": "Total number of unavailable pods targeted by this deployment. This is the total number of pods that are still required for the deployment to have 100% available capacity. They may either be pods that are running but not yet available or pods that still have not been created.", + "terminatingReplicas": "Total number of terminating pods targeted by this deployment. Terminating pods have a non-null .metadata.deletionTimestamp and have not yet reached the Failed or Succeeded .status.phase.\n\nThis is an alpha field. Enable DeploymentReplicaSetTerminatingReplicas to be able to use this field.", + "conditions": "Represents the latest available observations of a deployment's current state.", "collisionCount": "collisionCount is the count of hash collisions for the Deployment. The Deployment controller uses this field as a collision avoidance mechanism when it needs to create the name for the newest ReplicaSet.", } diff --git a/go-controller/vendor/k8s.io/api/apps/v1beta1/zz_generated.deepcopy.go b/go-controller/vendor/k8s.io/api/apps/v1beta1/zz_generated.deepcopy.go index dd73f1a5a9..e8594766c7 100644 --- a/go-controller/vendor/k8s.io/api/apps/v1beta1/zz_generated.deepcopy.go +++ b/go-controller/vendor/k8s.io/api/apps/v1beta1/zz_generated.deepcopy.go @@ -246,6 +246,11 @@ func (in *DeploymentSpec) DeepCopy() *DeploymentSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DeploymentStatus) DeepCopyInto(out *DeploymentStatus) { *out = *in + if in.TerminatingReplicas != nil { + in, out := &in.TerminatingReplicas, &out.TerminatingReplicas + *out = new(int32) + **out = **in + } if in.Conditions != nil { in, out := &in.Conditions, &out.Conditions *out = make([]DeploymentCondition, len(*in)) diff --git a/go-controller/vendor/k8s.io/api/apps/v1beta2/doc.go b/go-controller/vendor/k8s.io/api/apps/v1beta2/doc.go index ac91fddfd5..7d28fe42df 100644 --- a/go-controller/vendor/k8s.io/api/apps/v1beta2/doc.go +++ b/go-controller/vendor/k8s.io/api/apps/v1beta2/doc.go @@ -19,4 +19,4 @@ limitations under the License. // +k8s:openapi-gen=true // +k8s:prerelease-lifecycle-gen=true -package v1beta2 // import "k8s.io/api/apps/v1beta2" +package v1beta2 diff --git a/go-controller/vendor/k8s.io/api/apps/v1beta2/generated.pb.go b/go-controller/vendor/k8s.io/api/apps/v1beta2/generated.pb.go index 1c3d3be5bc..9fcba6feb1 100644 --- a/go-controller/vendor/k8s.io/api/apps/v1beta2/generated.pb.go +++ b/go-controller/vendor/k8s.io/api/apps/v1beta2/generated.pb.go @@ -1017,153 +1017,155 @@ func init() { } var fileDescriptor_c423c016abf485d4 = []byte{ - // 2328 bytes of a gzipped FileDescriptorProto + // 2359 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5a, 0xcd, 0x6f, 0x1b, 0xc7, - 0x15, 0xf7, 0xf2, 0x43, 0x26, 0x87, 0x96, 0x64, 0x8f, 0x54, 0x89, 0xb1, 0x5b, 0xd2, 0x58, 0x1b, - 0xb6, 0x12, 0xdb, 0xa4, 0xad, 0x7c, 0x20, 0xb1, 0xdb, 0x04, 0xa2, 0x94, 0xda, 0x0e, 0xf4, 0xc1, - 0x0c, 0x2d, 0x07, 0x0d, 0xfa, 0xe1, 0x11, 0x39, 0xa6, 0x36, 0xde, 0x2f, 0xec, 0x0e, 0x15, 0x13, - 0xbd, 0xf4, 0x5a, 0xa0, 0x40, 0xdb, 0x6b, 0xff, 0x89, 0xa2, 0x97, 0xa2, 0x68, 0xd0, 0x4b, 0x11, - 0x04, 0x3e, 0x06, 0xbd, 0x24, 0x27, 0xa2, 0x66, 0x4e, 0x45, 0xd1, 0x5b, 0x7b, 0x31, 0x50, 0xa0, - 0x98, 0xd9, 0xd9, 0xef, 0x5d, 0x73, 0xa9, 0xd8, 0x4a, 0x13, 0xe4, 0xc6, 0x9d, 0xf7, 0xde, 0x6f, - 0xde, 0xcc, 0xbc, 0x37, 0xef, 0x37, 0x33, 0x04, 0x17, 0x1f, 0xbc, 0x6e, 0x37, 0x14, 0xa3, 0x89, - 0x4d, 0xa5, 0x89, 0x4d, 0xd3, 0x6e, 0x1e, 0x5c, 0xdb, 0x23, 0x14, 0xaf, 0x36, 0xfb, 0x44, 0x27, - 0x16, 0xa6, 0xa4, 0xd7, 0x30, 0x2d, 0x83, 0x1a, 0x70, 0xd9, 0x51, 0x6c, 0x60, 0x53, 0x69, 0x30, - 0xc5, 0x86, 0x50, 0x3c, 0x7d, 0xa5, 0xaf, 0xd0, 0xfd, 0xc1, 0x5e, 0xa3, 0x6b, 0x68, 0xcd, 0xbe, - 0xd1, 0x37, 0x9a, 0x5c, 0x7f, 0x6f, 0x70, 0x9f, 0x7f, 0xf1, 0x0f, 0xfe, 0xcb, 0xc1, 0x39, 0x2d, - 0x07, 0x3a, 0xec, 0x1a, 0x16, 0x69, 0x1e, 0x5c, 0x8b, 0xf6, 0x75, 0xfa, 0x15, 0x5f, 0x47, 0xc3, - 0xdd, 0x7d, 0x45, 0x27, 0xd6, 0xb0, 0x69, 0x3e, 0xe8, 0xb3, 0x06, 0xbb, 0xa9, 0x11, 0x8a, 0x93, - 0xac, 0x9a, 0x69, 0x56, 0xd6, 0x40, 0xa7, 0x8a, 0x46, 0x62, 0x06, 0xaf, 0x4d, 0x32, 0xb0, 0xbb, - 0xfb, 0x44, 0xc3, 0x31, 0xbb, 0x97, 0xd3, 0xec, 0x06, 0x54, 0x51, 0x9b, 0x8a, 0x4e, 0x6d, 0x6a, - 0x45, 0x8d, 0xe4, 0xff, 0x48, 0x00, 0xae, 0x1b, 0x3a, 0xb5, 0x0c, 0x55, 0x25, 0x16, 0x22, 0x07, - 0x8a, 0xad, 0x18, 0x3a, 0xbc, 0x07, 0x4a, 0x6c, 0x3c, 0x3d, 0x4c, 0x71, 0x55, 0x3a, 0x2b, 0xad, - 0x54, 0x56, 0xaf, 0x36, 0xfc, 0x99, 0xf6, 0xe0, 0x1b, 0xe6, 0x83, 0x3e, 0x6b, 0xb0, 0x1b, 0x4c, - 0xbb, 0x71, 0x70, 0xad, 0xb1, 0xb3, 0xf7, 0x01, 0xe9, 0xd2, 0x2d, 0x42, 0x71, 0x0b, 0x3e, 0x1a, - 0xd5, 0x8f, 0x8d, 0x47, 0x75, 0xe0, 0xb7, 0x21, 0x0f, 0x15, 0xee, 0x80, 0x02, 0x47, 0xcf, 0x71, - 0xf4, 0x2b, 0xa9, 0xe8, 0x62, 0xd0, 0x0d, 0x84, 0x3f, 0x7c, 0xfb, 0x21, 0x25, 0x3a, 0x73, 0xaf, - 0x75, 0x42, 0x40, 0x17, 0x36, 0x30, 0xc5, 0x88, 0x03, 0xc1, 0xcb, 0xa0, 0x64, 0x09, 0xf7, 0xab, - 0xf9, 0xb3, 0xd2, 0x4a, 0xbe, 0x75, 0x52, 0x68, 0x95, 0xdc, 0x61, 0x21, 0x4f, 0x43, 0x7e, 0x24, - 0x81, 0xa5, 0xf8, 0xb8, 0x37, 0x15, 0x9b, 0xc2, 0x1f, 0xc7, 0xc6, 0xde, 0xc8, 0x36, 0x76, 0x66, - 0xcd, 0x47, 0xee, 0x75, 0xec, 0xb6, 0x04, 0xc6, 0xdd, 0x06, 0x45, 0x85, 0x12, 0xcd, 0xae, 0xe6, - 0xce, 0xe6, 0x57, 0x2a, 0xab, 0x97, 0x1a, 0x29, 0x01, 0xdc, 0x88, 0x7b, 0xd7, 0x9a, 0x15, 0xb8, - 0xc5, 0xdb, 0x0c, 0x01, 0x39, 0x40, 0xf2, 0x2f, 0x73, 0xa0, 0xbc, 0x81, 0x89, 0x66, 0xe8, 0x1d, - 0x42, 0x8f, 0x60, 0xe5, 0x6e, 0x81, 0x82, 0x6d, 0x92, 0xae, 0x58, 0xb9, 0x0b, 0xa9, 0x03, 0xf0, - 0x7c, 0xea, 0x98, 0xa4, 0xeb, 0x2f, 0x19, 0xfb, 0x42, 0x1c, 0x01, 0xb6, 0xc1, 0x8c, 0x4d, 0x31, - 0x1d, 0xd8, 0x7c, 0xc1, 0x2a, 0xab, 0x2b, 0x19, 0xb0, 0xb8, 0x7e, 0x6b, 0x4e, 0xa0, 0xcd, 0x38, - 0xdf, 0x48, 0xe0, 0xc8, 0xff, 0xc8, 0x01, 0xe8, 0xe9, 0xae, 0x1b, 0x7a, 0x4f, 0xa1, 0x2c, 0x9c, - 0xaf, 0x83, 0x02, 0x1d, 0x9a, 0x84, 0x4f, 0x48, 0xb9, 0x75, 0xc1, 0x75, 0xe5, 0xce, 0xd0, 0x24, - 0x4f, 0x46, 0xf5, 0xa5, 0xb8, 0x05, 0x93, 0x20, 0x6e, 0x03, 0x37, 0x3d, 0x27, 0x73, 0xdc, 0xfa, - 0x95, 0x70, 0xd7, 0x4f, 0x46, 0xf5, 0x84, 0xbd, 0xa3, 0xe1, 0x21, 0x85, 0x1d, 0x84, 0x07, 0x00, - 0xaa, 0xd8, 0xa6, 0x77, 0x2c, 0xac, 0xdb, 0x4e, 0x4f, 0x8a, 0x46, 0xc4, 0xf0, 0x5f, 0xca, 0xb6, - 0x50, 0xcc, 0xa2, 0x75, 0x5a, 0x78, 0x01, 0x37, 0x63, 0x68, 0x28, 0xa1, 0x07, 0x78, 0x01, 0xcc, - 0x58, 0x04, 0xdb, 0x86, 0x5e, 0x2d, 0xf0, 0x51, 0x78, 0x13, 0x88, 0x78, 0x2b, 0x12, 0x52, 0xf8, - 0x22, 0x38, 0xae, 0x11, 0xdb, 0xc6, 0x7d, 0x52, 0x2d, 0x72, 0xc5, 0x79, 0xa1, 0x78, 0x7c, 0xcb, - 0x69, 0x46, 0xae, 0x5c, 0xfe, 0xa3, 0x04, 0x66, 0xbd, 0x99, 0x3b, 0x82, 0xcc, 0xb9, 0x19, 0xce, - 0x1c, 0x79, 0x72, 0xb0, 0xa4, 0x24, 0xcc, 0xc7, 0xf9, 0x80, 0xe3, 0x2c, 0x1c, 0xe1, 0x4f, 0x40, - 0xc9, 0x26, 0x2a, 0xe9, 0x52, 0xc3, 0x12, 0x8e, 0xbf, 0x9c, 0xd1, 0x71, 0xbc, 0x47, 0xd4, 0x8e, - 0x30, 0x6d, 0x9d, 0x60, 0x9e, 0xbb, 0x5f, 0xc8, 0x83, 0x84, 0xef, 0x82, 0x12, 0x25, 0x9a, 0xa9, - 0x62, 0x4a, 0x44, 0xd6, 0x9c, 0x0b, 0x3a, 0xcf, 0x62, 0x86, 0x81, 0xb5, 0x8d, 0xde, 0x1d, 0xa1, - 0xc6, 0x53, 0xc6, 0x9b, 0x0c, 0xb7, 0x15, 0x79, 0x30, 0xd0, 0x04, 0x73, 0x03, 0xb3, 0xc7, 0x34, - 0x29, 0xdb, 0xce, 0xfb, 0x43, 0x11, 0x43, 0x57, 0x27, 0xcf, 0xca, 0x6e, 0xc8, 0xae, 0xb5, 0x24, - 0x7a, 0x99, 0x0b, 0xb7, 0xa3, 0x08, 0x3e, 0x5c, 0x03, 0xf3, 0x9a, 0xa2, 0x23, 0x82, 0x7b, 0xc3, - 0x0e, 0xe9, 0x1a, 0x7a, 0xcf, 0xe6, 0xa1, 0x54, 0x6c, 0x2d, 0x0b, 0x80, 0xf9, 0xad, 0xb0, 0x18, - 0x45, 0xf5, 0xe1, 0x26, 0x58, 0x74, 0x37, 0xe0, 0x5b, 0x8a, 0x4d, 0x0d, 0x6b, 0xb8, 0xa9, 0x68, - 0x0a, 0xad, 0xce, 0x70, 0x9c, 0xea, 0x78, 0x54, 0x5f, 0x44, 0x09, 0x72, 0x94, 0x68, 0x25, 0xff, - 0x76, 0x06, 0xcc, 0x47, 0xf6, 0x05, 0x78, 0x17, 0x2c, 0x75, 0x07, 0x96, 0x45, 0x74, 0xba, 0x3d, - 0xd0, 0xf6, 0x88, 0xd5, 0xe9, 0xee, 0x93, 0xde, 0x40, 0x25, 0x3d, 0xbe, 0xac, 0xc5, 0x56, 0x4d, - 0xf8, 0xba, 0xb4, 0x9e, 0xa8, 0x85, 0x52, 0xac, 0xe1, 0x3b, 0x00, 0xea, 0xbc, 0x69, 0x4b, 0xb1, - 0x6d, 0x0f, 0x33, 0xc7, 0x31, 0xbd, 0x54, 0xdc, 0x8e, 0x69, 0xa0, 0x04, 0x2b, 0xe6, 0x63, 0x8f, - 0xd8, 0x8a, 0x45, 0x7a, 0x51, 0x1f, 0xf3, 0x61, 0x1f, 0x37, 0x12, 0xb5, 0x50, 0x8a, 0x35, 0x7c, - 0x15, 0x54, 0x9c, 0xde, 0xf8, 0x9c, 0x8b, 0xc5, 0x59, 0x10, 0x60, 0x95, 0x6d, 0x5f, 0x84, 0x82, - 0x7a, 0x6c, 0x68, 0xc6, 0x9e, 0x4d, 0xac, 0x03, 0xd2, 0xbb, 0xe9, 0x90, 0x03, 0x56, 0x41, 0x8b, - 0xbc, 0x82, 0x7a, 0x43, 0xdb, 0x89, 0x69, 0xa0, 0x04, 0x2b, 0x36, 0x34, 0x27, 0x6a, 0x62, 0x43, - 0x9b, 0x09, 0x0f, 0x6d, 0x37, 0x51, 0x0b, 0xa5, 0x58, 0xb3, 0xd8, 0x73, 0x5c, 0x5e, 0x3b, 0xc0, - 0x8a, 0x8a, 0xf7, 0x54, 0x52, 0x3d, 0x1e, 0x8e, 0xbd, 0xed, 0xb0, 0x18, 0x45, 0xf5, 0xe1, 0x4d, - 0x70, 0xca, 0x69, 0xda, 0xd5, 0xb1, 0x07, 0x52, 0xe2, 0x20, 0x2f, 0x08, 0x90, 0x53, 0xdb, 0x51, - 0x05, 0x14, 0xb7, 0x81, 0xd7, 0xc1, 0x5c, 0xd7, 0x50, 0x55, 0x1e, 0x8f, 0xeb, 0xc6, 0x40, 0xa7, - 0xd5, 0x32, 0x47, 0x81, 0x2c, 0x87, 0xd6, 0x43, 0x12, 0x14, 0xd1, 0x84, 0x3f, 0x03, 0xa0, 0xeb, - 0x16, 0x06, 0xbb, 0x0a, 0x26, 0x30, 0x80, 0x78, 0x59, 0xf2, 0x2b, 0xb3, 0xd7, 0x64, 0xa3, 0x00, - 0xa4, 0xfc, 0xb1, 0x04, 0x96, 0x53, 0x12, 0x1d, 0xbe, 0x15, 0x2a, 0x82, 0x97, 0x22, 0x45, 0xf0, - 0x4c, 0x8a, 0x59, 0xa0, 0x12, 0xee, 0x83, 0x59, 0x46, 0x48, 0x14, 0xbd, 0xef, 0xa8, 0x88, 0xbd, - 0xac, 0x99, 0x3a, 0x00, 0x14, 0xd4, 0xf6, 0x77, 0xe5, 0x53, 0xe3, 0x51, 0x7d, 0x36, 0x24, 0x43, - 0x61, 0x60, 0xf9, 0x57, 0x39, 0x00, 0x36, 0x88, 0xa9, 0x1a, 0x43, 0x8d, 0xe8, 0x47, 0xc1, 0x69, - 0x6e, 0x87, 0x38, 0xcd, 0xc5, 0xf4, 0x25, 0xf1, 0x9c, 0x4a, 0x25, 0x35, 0xef, 0x46, 0x48, 0xcd, - 0x8b, 0x59, 0xc0, 0x9e, 0xce, 0x6a, 0x3e, 0xcb, 0x83, 0x05, 0x5f, 0xd9, 0xa7, 0x35, 0x37, 0x42, - 0x2b, 0x7a, 0x31, 0xb2, 0xa2, 0xcb, 0x09, 0x26, 0xcf, 0x8d, 0xd7, 0x7c, 0x00, 0xe6, 0x18, 0xeb, - 0x70, 0xd6, 0x8f, 0x73, 0x9a, 0x99, 0xa9, 0x39, 0x8d, 0x57, 0x89, 0x36, 0x43, 0x48, 0x28, 0x82, - 0x9c, 0xc2, 0xa1, 0x8e, 0x7f, 0x1d, 0x39, 0xd4, 0x9f, 0x24, 0x30, 0xe7, 0x2f, 0xd3, 0x11, 0x90, - 0xa8, 0x5b, 0x61, 0x12, 0x75, 0x2e, 0x43, 0x70, 0xa6, 0xb0, 0xa8, 0xcf, 0x0a, 0x41, 0xd7, 0x39, - 0x8d, 0x5a, 0x61, 0x47, 0x30, 0x53, 0x55, 0xba, 0xd8, 0x16, 0xf5, 0xf6, 0x84, 0x73, 0xfc, 0x72, - 0xda, 0x90, 0x27, 0x0d, 0x11, 0xae, 0xdc, 0xf3, 0x25, 0x5c, 0xf9, 0x67, 0x43, 0xb8, 0x7e, 0x04, - 0x4a, 0xb6, 0x4b, 0xb5, 0x0a, 0x1c, 0xf2, 0x52, 0xa6, 0xc4, 0x16, 0x2c, 0xcb, 0x83, 0xf6, 0xf8, - 0x95, 0x07, 0x97, 0xc4, 0xac, 0x8a, 0x5f, 0x25, 0xb3, 0x62, 0x81, 0x6e, 0xe2, 0x81, 0x4d, 0x7a, - 0x3c, 0xa9, 0x4a, 0x7e, 0xa0, 0xb7, 0x79, 0x2b, 0x12, 0x52, 0xb8, 0x0b, 0x96, 0x4d, 0xcb, 0xe8, - 0x5b, 0xc4, 0xb6, 0x37, 0x08, 0xee, 0xa9, 0x8a, 0x4e, 0xdc, 0x01, 0x38, 0x35, 0xf1, 0xcc, 0x78, - 0x54, 0x5f, 0x6e, 0x27, 0xab, 0xa0, 0x34, 0x5b, 0xf9, 0xaf, 0x05, 0x70, 0x32, 0xba, 0x37, 0xa6, - 0xd0, 0x14, 0xe9, 0x50, 0x34, 0xe5, 0x72, 0x20, 0x4e, 0x1d, 0x0e, 0x17, 0xb8, 0x2a, 0x88, 0xc5, - 0xea, 0x1a, 0x98, 0x17, 0xb4, 0xc4, 0x15, 0x0a, 0xa2, 0xe6, 0x2d, 0xcf, 0x6e, 0x58, 0x8c, 0xa2, - 0xfa, 0xf0, 0x06, 0x98, 0xb5, 0x38, 0xf3, 0x72, 0x01, 0x1c, 0xf6, 0xf2, 0x1d, 0x01, 0x30, 0x8b, - 0x82, 0x42, 0x14, 0xd6, 0x65, 0xcc, 0xc5, 0x27, 0x24, 0x2e, 0x40, 0x21, 0xcc, 0x5c, 0xd6, 0xa2, - 0x0a, 0x28, 0x6e, 0x03, 0xb7, 0xc0, 0xc2, 0x40, 0x8f, 0x43, 0x39, 0xb1, 0x76, 0x46, 0x40, 0x2d, - 0xec, 0xc6, 0x55, 0x50, 0x92, 0x1d, 0xbc, 0x17, 0x22, 0x33, 0x33, 0x7c, 0x3f, 0xb9, 0x9c, 0x21, - 0x27, 0x32, 0xb3, 0x99, 0x04, 0xaa, 0x55, 0xca, 0x4a, 0xb5, 0xe4, 0x8f, 0x24, 0x00, 0xe3, 0x79, - 0x38, 0xf1, 0x26, 0x20, 0x66, 0x11, 0xa8, 0x98, 0x4a, 0x32, 0xff, 0xb9, 0x9a, 0x91, 0xff, 0xf8, - 0x1b, 0x6a, 0x36, 0x02, 0x24, 0x26, 0xfa, 0x68, 0x2e, 0x75, 0xb2, 0x12, 0x20, 0xdf, 0xa9, 0x67, - 0x40, 0x80, 0x02, 0x60, 0x4f, 0x27, 0x40, 0xff, 0xcc, 0x81, 0x05, 0x5f, 0x39, 0x33, 0x01, 0x4a, - 0x30, 0xf9, 0xf6, 0x62, 0x27, 0x1b, 0x29, 0xf1, 0xa7, 0xee, 0xff, 0x89, 0x94, 0xf8, 0x5e, 0xa5, - 0x90, 0x92, 0xdf, 0xe7, 0x82, 0xae, 0x4f, 0x49, 0x4a, 0x9e, 0xc1, 0x0d, 0xc7, 0xd7, 0x8e, 0xd7, - 0xc8, 0x9f, 0xe4, 0xc1, 0xc9, 0x68, 0x1e, 0x86, 0x0a, 0xa4, 0x34, 0xb1, 0x40, 0xb6, 0xc1, 0xe2, - 0xfd, 0x81, 0xaa, 0x0e, 0xf9, 0x18, 0x02, 0x55, 0xd2, 0x29, 0xad, 0xdf, 0x15, 0x96, 0x8b, 0x3f, - 0x4c, 0xd0, 0x41, 0x89, 0x96, 0xf1, 0x7a, 0x59, 0xf8, 0xb2, 0xf5, 0xb2, 0x78, 0x88, 0x7a, 0x99, - 0x4c, 0x39, 0xf2, 0x87, 0xa2, 0x1c, 0xd3, 0x15, 0xcb, 0x84, 0x8d, 0x6b, 0xe2, 0xd1, 0x7f, 0x2c, - 0x81, 0xa5, 0xe4, 0x03, 0x37, 0x54, 0xc1, 0x9c, 0x86, 0x1f, 0x06, 0x2f, 0x3e, 0x26, 0x15, 0x91, - 0x01, 0x55, 0xd4, 0x86, 0xf3, 0x64, 0xd4, 0xb8, 0xad, 0xd3, 0x1d, 0xab, 0x43, 0x2d, 0x45, 0xef, - 0x3b, 0x95, 0x77, 0x2b, 0x84, 0x85, 0x22, 0xd8, 0xf0, 0x7d, 0x50, 0xd2, 0xf0, 0xc3, 0xce, 0xc0, - 0xea, 0x27, 0x55, 0xc8, 0x6c, 0xfd, 0xf0, 0x04, 0xd8, 0x12, 0x28, 0xc8, 0xc3, 0x93, 0xbf, 0x90, - 0xc0, 0x72, 0x4a, 0x55, 0xfd, 0x06, 0x8d, 0xf2, 0x2f, 0x12, 0x38, 0x1b, 0x1a, 0x25, 0x4b, 0x4b, - 0x72, 0x7f, 0xa0, 0xf2, 0x0c, 0x15, 0x4c, 0xe6, 0x12, 0x28, 0x9b, 0xd8, 0xa2, 0x8a, 0xc7, 0x83, - 0x8b, 0xad, 0xd9, 0xf1, 0xa8, 0x5e, 0x6e, 0xbb, 0x8d, 0xc8, 0x97, 0x27, 0xcc, 0x4d, 0xee, 0xf9, - 0xcd, 0x8d, 0xfc, 0x5f, 0x09, 0x14, 0x3b, 0x5d, 0xac, 0x92, 0x23, 0x20, 0x2e, 0x1b, 0x21, 0xe2, - 0x92, 0xfe, 0x28, 0xc0, 0xfd, 0x49, 0xe5, 0x2c, 0x9b, 0x11, 0xce, 0x72, 0x7e, 0x02, 0xce, 0xd3, - 0xe9, 0xca, 0x1b, 0xa0, 0xec, 0x75, 0x37, 0xdd, 0x5e, 0x2a, 0xff, 0x2e, 0x07, 0x2a, 0x81, 0x2e, - 0xa6, 0xdc, 0x89, 0xef, 0x85, 0xca, 0x0f, 0xdb, 0x63, 0x56, 0xb3, 0x0c, 0xa4, 0xe1, 0x96, 0x9a, - 0xb7, 0x75, 0x6a, 0x05, 0xcf, 0xaa, 0xf1, 0x0a, 0xf4, 0x26, 0x98, 0xa3, 0xd8, 0xea, 0x13, 0xea, - 0xca, 0xf8, 0x84, 0x95, 0xfd, 0xbb, 0x9b, 0x3b, 0x21, 0x29, 0x8a, 0x68, 0x9f, 0xbe, 0x01, 0x66, - 0x43, 0x9d, 0xc1, 0x93, 0x20, 0xff, 0x80, 0x0c, 0x1d, 0x06, 0x87, 0xd8, 0x4f, 0xb8, 0x08, 0x8a, - 0x07, 0x58, 0x1d, 0x38, 0x21, 0x5a, 0x46, 0xce, 0xc7, 0xf5, 0xdc, 0xeb, 0x92, 0xfc, 0x6b, 0x36, - 0x39, 0x7e, 0x2a, 0x1c, 0x41, 0x74, 0xbd, 0x13, 0x8a, 0xae, 0xf4, 0xf7, 0xc9, 0x60, 0x82, 0xa6, - 0xc5, 0x18, 0x8a, 0xc4, 0xd8, 0x4b, 0x99, 0xd0, 0x9e, 0x1e, 0x69, 0xff, 0xca, 0x81, 0xc5, 0x80, - 0xb6, 0xcf, 0x8c, 0xbf, 0x1f, 0x62, 0xc6, 0x2b, 0x11, 0x66, 0x5c, 0x4d, 0xb2, 0xf9, 0x96, 0x1a, - 0x4f, 0xa6, 0xc6, 0x7f, 0x96, 0xc0, 0x7c, 0x60, 0xee, 0x8e, 0x80, 0x1b, 0xdf, 0x0e, 0x73, 0xe3, - 0xf3, 0x59, 0x82, 0x26, 0x85, 0x1c, 0x5f, 0x07, 0x0b, 0x01, 0xa5, 0x1d, 0xab, 0xa7, 0xe8, 0x58, - 0xb5, 0xe1, 0x39, 0x50, 0xb4, 0x29, 0xb6, 0xa8, 0x5b, 0x44, 0x5c, 0xdb, 0x0e, 0x6b, 0x44, 0x8e, - 0x4c, 0xfe, 0xb7, 0x04, 0x9a, 0x01, 0xe3, 0x36, 0xb1, 0x6c, 0xc5, 0xa6, 0x44, 0xa7, 0x77, 0x0d, - 0x75, 0xa0, 0x91, 0x75, 0x15, 0x2b, 0x1a, 0x22, 0xac, 0x41, 0x31, 0xf4, 0xb6, 0xa1, 0x2a, 0xdd, - 0x21, 0xc4, 0xa0, 0xf2, 0xe1, 0x3e, 0xd1, 0x37, 0x88, 0x4a, 0xa8, 0x78, 0x81, 0x2b, 0xb7, 0xde, - 0x72, 0x1f, 0xa4, 0xde, 0xf3, 0x45, 0x4f, 0x46, 0xf5, 0x95, 0x2c, 0x88, 0x3c, 0x42, 0x83, 0x98, - 0xf0, 0xa7, 0x00, 0xb0, 0x4f, 0xbe, 0x97, 0xf5, 0x44, 0xb0, 0xbe, 0xe9, 0x66, 0xf4, 0x7b, 0x9e, - 0x64, 0xaa, 0x0e, 0x02, 0x88, 0xf2, 0x1f, 0x4a, 0xa1, 0xf5, 0xfe, 0xc6, 0xdf, 0x72, 0xfe, 0x1c, - 0x2c, 0x1e, 0xf8, 0xb3, 0xe3, 0x2a, 0x30, 0xfe, 0x9d, 0x8f, 0x9e, 0xe4, 0x3d, 0xf8, 0xa4, 0x79, - 0xf5, 0x59, 0xff, 0xdd, 0x04, 0x38, 0x94, 0xd8, 0x09, 0x7c, 0x15, 0x54, 0x18, 0x6f, 0x56, 0xba, - 0x64, 0x1b, 0x6b, 0x6e, 0x2e, 0x7a, 0x0f, 0x98, 0x1d, 0x5f, 0x84, 0x82, 0x7a, 0x70, 0x1f, 0x2c, - 0x98, 0x46, 0x6f, 0x0b, 0xeb, 0xb8, 0x4f, 0x18, 0x11, 0x74, 0x96, 0x92, 0x5f, 0x7d, 0x96, 0x5b, - 0xaf, 0xb9, 0xd7, 0x5a, 0xed, 0xb8, 0xca, 0x93, 0x51, 0x7d, 0x39, 0xa1, 0x99, 0x07, 0x41, 0x12, - 0x24, 0xb4, 0x62, 0x8f, 0xee, 0xce, 0xa3, 0xc3, 0x6a, 0x96, 0xa4, 0x3c, 0xe4, 0xb3, 0x7b, 0xda, - 0xcd, 0x6e, 0xe9, 0x50, 0x37, 0xbb, 0x09, 0x47, 0xdc, 0xf2, 0x94, 0x47, 0xdc, 0x4f, 0x24, 0x70, - 0xde, 0xcc, 0x90, 0x4b, 0x55, 0xc0, 0xe7, 0xe6, 0x56, 0x96, 0xb9, 0xc9, 0x92, 0x9b, 0xad, 0x95, - 0xf1, 0xa8, 0x7e, 0x3e, 0x8b, 0x26, 0xca, 0xe4, 0x1f, 0xbc, 0x0b, 0x4a, 0x86, 0xd8, 0x03, 0xab, - 0x15, 0xee, 0xeb, 0xe5, 0x2c, 0xbe, 0xba, 0xfb, 0xa6, 0x93, 0x96, 0xee, 0x17, 0xf2, 0xb0, 0xe4, - 0x8f, 0x8a, 0xe0, 0x54, 0xac, 0x82, 0x7f, 0x85, 0xf7, 0xd7, 0xb1, 0xc3, 0x74, 0x7e, 0x8a, 0xc3, - 0xf4, 0x1a, 0x98, 0x17, 0x7f, 0x89, 0x88, 0x9c, 0xc5, 0xbd, 0x80, 0x59, 0x0f, 0x8b, 0x51, 0x54, - 0x3f, 0xe9, 0xfe, 0xbc, 0x38, 0xe5, 0xfd, 0x79, 0xd0, 0x0b, 0xf1, 0x17, 0x3f, 0x27, 0xbd, 0xe3, - 0x5e, 0x88, 0x7f, 0xfa, 0x45, 0xf5, 0x19, 0x71, 0x75, 0x50, 0x3d, 0x84, 0xe3, 0x61, 0xe2, 0xba, - 0x1b, 0x92, 0xa2, 0x88, 0xf6, 0x97, 0x7a, 0xf6, 0xc7, 0x09, 0xcf, 0xfe, 0x57, 0xb2, 0xc4, 0x5a, - 0xf6, 0xab, 0xf2, 0xc4, 0x4b, 0x8f, 0xca, 0xf4, 0x97, 0x1e, 0xf2, 0xdf, 0x24, 0xf0, 0x42, 0xea, - 0xae, 0x05, 0xd7, 0x42, 0xb4, 0xf2, 0x4a, 0x84, 0x56, 0x7e, 0x2f, 0xd5, 0x30, 0xc0, 0x2d, 0xad, - 0xe4, 0x5b, 0xf4, 0x37, 0xb2, 0xdd, 0xa2, 0x27, 0x9c, 0x84, 0x27, 0x5f, 0xa7, 0xb7, 0x7e, 0xf0, - 0xe8, 0x71, 0xed, 0xd8, 0xa7, 0x8f, 0x6b, 0xc7, 0x3e, 0x7f, 0x5c, 0x3b, 0xf6, 0x8b, 0x71, 0x4d, - 0x7a, 0x34, 0xae, 0x49, 0x9f, 0x8e, 0x6b, 0xd2, 0xe7, 0xe3, 0x9a, 0xf4, 0xf7, 0x71, 0x4d, 0xfa, - 0xcd, 0x17, 0xb5, 0x63, 0xef, 0x2f, 0xa7, 0xfc, 0xe9, 0xf8, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, - 0xa4, 0x79, 0xcd, 0x52, 0x8e, 0x2c, 0x00, 0x00, + 0x15, 0xf7, 0x92, 0xa2, 0x44, 0x0e, 0x2d, 0xc9, 0x1e, 0xa9, 0x22, 0x63, 0xb7, 0xa4, 0xb1, 0x36, + 0x6c, 0x25, 0xb6, 0x49, 0x5b, 0xf9, 0x40, 0x62, 0xb7, 0x09, 0x44, 0x29, 0xb5, 0x1d, 0x48, 0x32, + 0x33, 0xb4, 0x1c, 0x34, 0xe8, 0x87, 0x47, 0xe4, 0x98, 0xda, 0x78, 0xbf, 0xb0, 0x3b, 0x54, 0x4c, + 0xf4, 0xd2, 0x6b, 0x81, 0x16, 0x6d, 0xae, 0xfd, 0x27, 0x8a, 0x5e, 0x8a, 0xa2, 0x41, 0x6f, 0x41, + 0xe1, 0x63, 0xd0, 0x4b, 0x72, 0x22, 0x6a, 0xe6, 0x54, 0x14, 0xbd, 0xb5, 0x17, 0x03, 0x05, 0x8a, + 0x99, 0x9d, 0xfd, 0xde, 0x35, 0x97, 0x8a, 0xad, 0x34, 0x41, 0x6e, 0xdc, 0x79, 0xef, 0xfd, 0xe6, + 0xcd, 0xcc, 0x7b, 0xf3, 0x7e, 0xfb, 0xb8, 0xe0, 0xc2, 0x83, 0xd7, 0xed, 0x86, 0x62, 0x34, 0xb1, + 0xa9, 0x34, 0xb1, 0x69, 0xda, 0xcd, 0x83, 0xab, 0x7b, 0x84, 0xe2, 0xb5, 0x66, 0x9f, 0xe8, 0xc4, + 0xc2, 0x94, 0xf4, 0x1a, 0xa6, 0x65, 0x50, 0x03, 0x56, 0x1c, 0xc5, 0x06, 0x36, 0x95, 0x06, 0x53, + 0x6c, 0x08, 0xc5, 0x53, 0x97, 0xfb, 0x0a, 0xdd, 0x1f, 0xec, 0x35, 0xba, 0x86, 0xd6, 0xec, 0x1b, + 0x7d, 0xa3, 0xc9, 0xf5, 0xf7, 0x06, 0xf7, 0xf9, 0x13, 0x7f, 0xe0, 0xbf, 0x1c, 0x9c, 0x53, 0x72, + 0x60, 0xc2, 0xae, 0x61, 0x91, 0xe6, 0xc1, 0xd5, 0xe8, 0x5c, 0xa7, 0x5e, 0xf1, 0x75, 0x34, 0xdc, + 0xdd, 0x57, 0x74, 0x62, 0x0d, 0x9b, 0xe6, 0x83, 0x3e, 0x1b, 0xb0, 0x9b, 0x1a, 0xa1, 0x38, 0xc9, + 0xaa, 0x99, 0x66, 0x65, 0x0d, 0x74, 0xaa, 0x68, 0x24, 0x66, 0xf0, 0xda, 0x24, 0x03, 0xbb, 0xbb, + 0x4f, 0x34, 0x1c, 0xb3, 0x7b, 0x39, 0xcd, 0x6e, 0x40, 0x15, 0xb5, 0xa9, 0xe8, 0xd4, 0xa6, 0x56, + 0xd4, 0x48, 0xfe, 0x8f, 0x04, 0xe0, 0x86, 0xa1, 0x53, 0xcb, 0x50, 0x55, 0x62, 0x21, 0x72, 0xa0, + 0xd8, 0x8a, 0xa1, 0xc3, 0x7b, 0xa0, 0xc8, 0xd6, 0xd3, 0xc3, 0x14, 0x57, 0xa5, 0x33, 0xd2, 0x6a, + 0x79, 0xed, 0x4a, 0xc3, 0xdf, 0x69, 0x0f, 0xbe, 0x61, 0x3e, 0xe8, 0xb3, 0x01, 0xbb, 0xc1, 0xb4, + 0x1b, 0x07, 0x57, 0x1b, 0xb7, 0xf7, 0x3e, 0x20, 0x5d, 0xba, 0x4d, 0x28, 0x6e, 0xc1, 0x47, 0xa3, + 0xfa, 0xb1, 0xf1, 0xa8, 0x0e, 0xfc, 0x31, 0xe4, 0xa1, 0xc2, 0xdb, 0x60, 0x86, 0xa3, 0xe7, 0x38, + 0xfa, 0xe5, 0x54, 0x74, 0xb1, 0xe8, 0x06, 0xc2, 0x1f, 0xbe, 0xfd, 0x90, 0x12, 0x9d, 0xb9, 0xd7, + 0x3a, 0x2e, 0xa0, 0x67, 0x36, 0x31, 0xc5, 0x88, 0x03, 0xc1, 0x4b, 0xa0, 0x68, 0x09, 0xf7, 0xab, + 0xf9, 0x33, 0xd2, 0x6a, 0xbe, 0x75, 0x42, 0x68, 0x15, 0xdd, 0x65, 0x21, 0x4f, 0x43, 0x7e, 0x24, + 0x81, 0x95, 0xf8, 0xba, 0xb7, 0x14, 0x9b, 0xc2, 0x1f, 0xc7, 0xd6, 0xde, 0xc8, 0xb6, 0x76, 0x66, + 0xcd, 0x57, 0xee, 0x4d, 0xec, 0x8e, 0x04, 0xd6, 0xdd, 0x06, 0x05, 0x85, 0x12, 0xcd, 0xae, 0xe6, + 0xce, 0xe4, 0x57, 0xcb, 0x6b, 0x17, 0x1b, 0x29, 0x01, 0xdc, 0x88, 0x7b, 0xd7, 0x9a, 0x17, 0xb8, + 0x85, 0x5b, 0x0c, 0x01, 0x39, 0x40, 0xf2, 0x2f, 0x73, 0xa0, 0xb4, 0x89, 0x89, 0x66, 0xe8, 0x1d, + 0x42, 0x8f, 0xe0, 0xe4, 0x6e, 0x82, 0x19, 0xdb, 0x24, 0x5d, 0x71, 0x72, 0xe7, 0x53, 0x17, 0xe0, + 0xf9, 0xd4, 0x31, 0x49, 0xd7, 0x3f, 0x32, 0xf6, 0x84, 0x38, 0x02, 0x6c, 0x83, 0x59, 0x9b, 0x62, + 0x3a, 0xb0, 0xf9, 0x81, 0x95, 0xd7, 0x56, 0x33, 0x60, 0x71, 0xfd, 0xd6, 0x82, 0x40, 0x9b, 0x75, + 0x9e, 0x91, 0xc0, 0x91, 0xff, 0x91, 0x03, 0xd0, 0xd3, 0xdd, 0x30, 0xf4, 0x9e, 0x42, 0x59, 0x38, + 0x5f, 0x03, 0x33, 0x74, 0x68, 0x12, 0xbe, 0x21, 0xa5, 0xd6, 0x79, 0xd7, 0x95, 0x3b, 0x43, 0x93, + 0x3c, 0x19, 0xd5, 0x57, 0xe2, 0x16, 0x4c, 0x82, 0xb8, 0x0d, 0xdc, 0xf2, 0x9c, 0xcc, 0x71, 0xeb, + 0x57, 0xc2, 0x53, 0x3f, 0x19, 0xd5, 0x13, 0xee, 0x8e, 0x86, 0x87, 0x14, 0x76, 0x10, 0x1e, 0x00, + 0xa8, 0x62, 0x9b, 0xde, 0xb1, 0xb0, 0x6e, 0x3b, 0x33, 0x29, 0x1a, 0x11, 0xcb, 0x7f, 0x29, 0xdb, + 0x41, 0x31, 0x8b, 0xd6, 0x29, 0xe1, 0x05, 0xdc, 0x8a, 0xa1, 0xa1, 0x84, 0x19, 0xe0, 0x79, 0x30, + 0x6b, 0x11, 0x6c, 0x1b, 0x7a, 0x75, 0x86, 0xaf, 0xc2, 0xdb, 0x40, 0xc4, 0x47, 0x91, 0x90, 0xc2, + 0x17, 0xc1, 0x9c, 0x46, 0x6c, 0x1b, 0xf7, 0x49, 0xb5, 0xc0, 0x15, 0x17, 0x85, 0xe2, 0xdc, 0xb6, + 0x33, 0x8c, 0x5c, 0xb9, 0xfc, 0x47, 0x09, 0xcc, 0x7b, 0x3b, 0x77, 0x04, 0x99, 0x73, 0x23, 0x9c, + 0x39, 0xf2, 0xe4, 0x60, 0x49, 0x49, 0x98, 0x4f, 0xf2, 0x01, 0xc7, 0x59, 0x38, 0xc2, 0x9f, 0x80, + 0xa2, 0x4d, 0x54, 0xd2, 0xa5, 0x86, 0x25, 0x1c, 0x7f, 0x39, 0xa3, 0xe3, 0x78, 0x8f, 0xa8, 0x1d, + 0x61, 0xda, 0x3a, 0xce, 0x3c, 0x77, 0x9f, 0x90, 0x07, 0x09, 0xdf, 0x05, 0x45, 0x4a, 0x34, 0x53, + 0xc5, 0x94, 0x88, 0xac, 0x39, 0x1b, 0x74, 0x9e, 0xc5, 0x0c, 0x03, 0x6b, 0x1b, 0xbd, 0x3b, 0x42, + 0x8d, 0xa7, 0x8c, 0xb7, 0x19, 0xee, 0x28, 0xf2, 0x60, 0xa0, 0x09, 0x16, 0x06, 0x66, 0x8f, 0x69, + 0x52, 0x76, 0x9d, 0xf7, 0x87, 0x22, 0x86, 0xae, 0x4c, 0xde, 0x95, 0xdd, 0x90, 0x5d, 0x6b, 0x45, + 0xcc, 0xb2, 0x10, 0x1e, 0x47, 0x11, 0x7c, 0xb8, 0x0e, 0x16, 0x35, 0x45, 0x47, 0x04, 0xf7, 0x86, + 0x1d, 0xd2, 0x35, 0xf4, 0x9e, 0xcd, 0x43, 0xa9, 0xd0, 0xaa, 0x08, 0x80, 0xc5, 0xed, 0xb0, 0x18, + 0x45, 0xf5, 0xe1, 0x16, 0x58, 0x76, 0x2f, 0xe0, 0x9b, 0x8a, 0x4d, 0x0d, 0x6b, 0xb8, 0xa5, 0x68, + 0x0a, 0xad, 0xce, 0x72, 0x9c, 0xea, 0x78, 0x54, 0x5f, 0x46, 0x09, 0x72, 0x94, 0x68, 0x25, 0x7f, + 0x34, 0x0b, 0x16, 0x23, 0xf7, 0x02, 0xbc, 0x0b, 0x56, 0xba, 0x03, 0xcb, 0x22, 0x3a, 0xdd, 0x19, + 0x68, 0x7b, 0xc4, 0xea, 0x74, 0xf7, 0x49, 0x6f, 0xa0, 0x92, 0x1e, 0x3f, 0xd6, 0x42, 0xab, 0x26, + 0x7c, 0x5d, 0xd9, 0x48, 0xd4, 0x42, 0x29, 0xd6, 0xf0, 0x1d, 0x00, 0x75, 0x3e, 0xb4, 0xad, 0xd8, + 0xb6, 0x87, 0x99, 0xe3, 0x98, 0x5e, 0x2a, 0xee, 0xc4, 0x34, 0x50, 0x82, 0x15, 0xf3, 0xb1, 0x47, + 0x6c, 0xc5, 0x22, 0xbd, 0xa8, 0x8f, 0xf9, 0xb0, 0x8f, 0x9b, 0x89, 0x5a, 0x28, 0xc5, 0x1a, 0xbe, + 0x0a, 0xca, 0xce, 0x6c, 0x7c, 0xcf, 0xc5, 0xe1, 0x2c, 0x09, 0xb0, 0xf2, 0x8e, 0x2f, 0x42, 0x41, + 0x3d, 0xb6, 0x34, 0x63, 0xcf, 0x26, 0xd6, 0x01, 0xe9, 0xdd, 0x70, 0xc8, 0x01, 0xab, 0xa0, 0x05, + 0x5e, 0x41, 0xbd, 0xa5, 0xdd, 0x8e, 0x69, 0xa0, 0x04, 0x2b, 0xb6, 0x34, 0x27, 0x6a, 0x62, 0x4b, + 0x9b, 0x0d, 0x2f, 0x6d, 0x37, 0x51, 0x0b, 0xa5, 0x58, 0xb3, 0xd8, 0x73, 0x5c, 0x5e, 0x3f, 0xc0, + 0x8a, 0x8a, 0xf7, 0x54, 0x52, 0x9d, 0x0b, 0xc7, 0xde, 0x4e, 0x58, 0x8c, 0xa2, 0xfa, 0xf0, 0x06, + 0x38, 0xe9, 0x0c, 0xed, 0xea, 0xd8, 0x03, 0x29, 0x72, 0x90, 0x17, 0x04, 0xc8, 0xc9, 0x9d, 0xa8, + 0x02, 0x8a, 0xdb, 0xc0, 0x6b, 0x60, 0xa1, 0x6b, 0xa8, 0x2a, 0x8f, 0xc7, 0x0d, 0x63, 0xa0, 0xd3, + 0x6a, 0x89, 0xa3, 0x40, 0x96, 0x43, 0x1b, 0x21, 0x09, 0x8a, 0x68, 0xc2, 0x9f, 0x01, 0xd0, 0x75, + 0x0b, 0x83, 0x5d, 0x05, 0x13, 0x18, 0x40, 0xbc, 0x2c, 0xf9, 0x95, 0xd9, 0x1b, 0xb2, 0x51, 0x00, + 0x52, 0xfe, 0x44, 0x02, 0x95, 0x94, 0x44, 0x87, 0x6f, 0x85, 0x8a, 0xe0, 0xc5, 0x48, 0x11, 0x3c, + 0x9d, 0x62, 0x16, 0xa8, 0x84, 0xfb, 0x60, 0x9e, 0x11, 0x12, 0x45, 0xef, 0x3b, 0x2a, 0xe2, 0x2e, + 0x6b, 0xa6, 0x2e, 0x00, 0x05, 0xb5, 0xfd, 0x5b, 0xf9, 0xe4, 0x78, 0x54, 0x9f, 0x0f, 0xc9, 0x50, + 0x18, 0x58, 0xfe, 0x55, 0x0e, 0x80, 0x4d, 0x62, 0xaa, 0xc6, 0x50, 0x23, 0xfa, 0x51, 0x70, 0x9a, + 0x5b, 0x21, 0x4e, 0x73, 0x21, 0xfd, 0x48, 0x3c, 0xa7, 0x52, 0x49, 0xcd, 0xbb, 0x11, 0x52, 0xf3, + 0x62, 0x16, 0xb0, 0xa7, 0xb3, 0x9a, 0xcf, 0xf2, 0x60, 0xc9, 0x57, 0xf6, 0x69, 0xcd, 0xf5, 0xd0, + 0x89, 0x5e, 0x88, 0x9c, 0x68, 0x25, 0xc1, 0xe4, 0xb9, 0xf1, 0x9a, 0x0f, 0xc0, 0x02, 0x63, 0x1d, + 0xce, 0xf9, 0x71, 0x4e, 0x33, 0x3b, 0x35, 0xa7, 0xf1, 0x2a, 0xd1, 0x56, 0x08, 0x09, 0x45, 0x90, + 0x53, 0x38, 0xd4, 0xdc, 0xd7, 0x91, 0x43, 0xfd, 0x49, 0x02, 0x0b, 0xfe, 0x31, 0x1d, 0x01, 0x89, + 0xba, 0x19, 0x26, 0x51, 0x67, 0x33, 0x04, 0x67, 0x0a, 0x8b, 0xfa, 0x6c, 0x26, 0xe8, 0x3a, 0xa7, + 0x51, 0xab, 0xec, 0x15, 0xcc, 0x54, 0x95, 0x2e, 0xb6, 0x45, 0xbd, 0x3d, 0xee, 0xbc, 0x7e, 0x39, + 0x63, 0xc8, 0x93, 0x86, 0x08, 0x57, 0xee, 0xf9, 0x12, 0xae, 0xfc, 0xb3, 0x21, 0x5c, 0x3f, 0x02, + 0x45, 0xdb, 0xa5, 0x5a, 0x33, 0x1c, 0xf2, 0x62, 0xa6, 0xc4, 0x16, 0x2c, 0xcb, 0x83, 0xf6, 0xf8, + 0x95, 0x07, 0x97, 0xc4, 0xac, 0x0a, 0x5f, 0x25, 0xb3, 0x62, 0x81, 0x6e, 0xe2, 0x81, 0x4d, 0x7a, + 0x3c, 0xa9, 0x8a, 0x7e, 0xa0, 0xb7, 0xf9, 0x28, 0x12, 0x52, 0xb8, 0x0b, 0x2a, 0xa6, 0x65, 0xf4, + 0x2d, 0x62, 0xdb, 0x9b, 0x04, 0xf7, 0x54, 0x45, 0x27, 0xee, 0x02, 0x9c, 0x9a, 0x78, 0x7a, 0x3c, + 0xaa, 0x57, 0xda, 0xc9, 0x2a, 0x28, 0xcd, 0x56, 0xfe, 0x75, 0x01, 0x9c, 0x88, 0xde, 0x8d, 0x29, + 0x34, 0x45, 0x3a, 0x14, 0x4d, 0xb9, 0x14, 0x88, 0x53, 0x87, 0xc3, 0x05, 0x5a, 0x05, 0xb1, 0x58, + 0x5d, 0x07, 0x8b, 0x82, 0x96, 0xb8, 0x42, 0x41, 0xd4, 0xbc, 0xe3, 0xd9, 0x0d, 0x8b, 0x51, 0x54, + 0x1f, 0x5e, 0x07, 0xf3, 0x16, 0x67, 0x5e, 0x2e, 0x80, 0xc3, 0x5e, 0xbe, 0x23, 0x00, 0xe6, 0x51, + 0x50, 0x88, 0xc2, 0xba, 0x8c, 0xb9, 0xf8, 0x84, 0xc4, 0x05, 0x98, 0x09, 0x33, 0x97, 0xf5, 0xa8, + 0x02, 0x8a, 0xdb, 0xc0, 0x6d, 0xb0, 0x34, 0xd0, 0xe3, 0x50, 0x4e, 0xac, 0x9d, 0x16, 0x50, 0x4b, + 0xbb, 0x71, 0x15, 0x94, 0x64, 0x07, 0x6f, 0x81, 0x25, 0x4a, 0x2c, 0x4d, 0xd1, 0x31, 0x55, 0xf4, + 0xbe, 0x07, 0xe7, 0x9c, 0x7c, 0x85, 0x41, 0xdd, 0x89, 0x8b, 0x51, 0x92, 0x0d, 0xbc, 0x17, 0xe2, + 0x45, 0xb3, 0xfc, 0x6a, 0xba, 0x94, 0x21, 0xbd, 0x32, 0x13, 0xa3, 0x04, 0xd6, 0x56, 0xcc, 0xca, + 0xda, 0xe4, 0x8f, 0x25, 0x00, 0xe3, 0x29, 0x3d, 0xb1, 0xa9, 0x10, 0xb3, 0x08, 0x14, 0x5f, 0x25, + 0x99, 0x4a, 0x5d, 0xc9, 0x48, 0xa5, 0xfc, 0xbb, 0x39, 0x1b, 0x97, 0x12, 0x1b, 0x7d, 0x34, 0xfd, + 0xa1, 0xac, 0x5c, 0xca, 0x77, 0xea, 0x19, 0x70, 0xa9, 0x00, 0xd8, 0xd3, 0xb9, 0xd4, 0x3f, 0x73, + 0x60, 0xc9, 0x57, 0xce, 0xcc, 0xa5, 0x12, 0x4c, 0xbe, 0xed, 0x11, 0x65, 0xe3, 0x37, 0xfe, 0xd6, + 0xfd, 0x3f, 0xf1, 0x1b, 0xdf, 0xab, 0x14, 0x7e, 0xf3, 0xfb, 0x5c, 0xd0, 0xf5, 0x29, 0xf9, 0xcd, + 0x33, 0x68, 0x96, 0x7c, 0xed, 0x28, 0x92, 0xfc, 0xd1, 0x0c, 0x38, 0x11, 0xcd, 0xc3, 0x50, 0xad, + 0x95, 0x26, 0xd6, 0xda, 0x36, 0x58, 0xbe, 0x3f, 0x50, 0xd5, 0x21, 0x5f, 0x43, 0xa0, 0xe0, 0x3a, + 0x55, 0xfa, 0xbb, 0xc2, 0x72, 0xf9, 0x87, 0x09, 0x3a, 0x28, 0xd1, 0x32, 0x5e, 0x7a, 0x67, 0xbe, + 0x6c, 0xe9, 0x2d, 0x1c, 0xa2, 0xf4, 0xa6, 0xd4, 0xca, 0xb9, 0x43, 0xd4, 0xca, 0x64, 0x22, 0x94, + 0x3f, 0x14, 0x11, 0x9a, 0xae, 0xee, 0x26, 0xdc, 0x81, 0x13, 0x1b, 0x12, 0x63, 0x09, 0xac, 0x24, + 0xb7, 0x01, 0xa0, 0x0a, 0x16, 0x34, 0xfc, 0x30, 0xd8, 0x8e, 0x99, 0x54, 0x8f, 0x06, 0x54, 0x51, + 0x1b, 0xce, 0x1f, 0x59, 0x8d, 0x5b, 0x3a, 0xbd, 0x6d, 0x75, 0xa8, 0xa5, 0xe8, 0x7d, 0xa7, 0x88, + 0x6f, 0x87, 0xb0, 0x50, 0x04, 0x1b, 0xbe, 0x0f, 0x8a, 0x1a, 0x7e, 0xd8, 0x19, 0x58, 0xfd, 0xa4, + 0x62, 0x9b, 0x6d, 0x1e, 0x9e, 0x4b, 0xdb, 0x02, 0x05, 0x79, 0x78, 0xf2, 0x17, 0x12, 0xa8, 0xa4, + 0x14, 0xe8, 0x6f, 0xd0, 0x2a, 0xff, 0x22, 0x81, 0x33, 0xa1, 0x55, 0xb2, 0x0c, 0x27, 0xf7, 0x07, + 0x2a, 0x4f, 0x76, 0x41, 0x8a, 0x2e, 0x82, 0x92, 0x89, 0x2d, 0xaa, 0x78, 0xec, 0xbc, 0xd0, 0x9a, + 0x1f, 0x8f, 0xea, 0xa5, 0xb6, 0x3b, 0x88, 0x7c, 0x79, 0xc2, 0xde, 0xe4, 0x9e, 0xdf, 0xde, 0xc8, + 0xff, 0x95, 0x40, 0xa1, 0xd3, 0xc5, 0x2a, 0x39, 0x02, 0x0e, 0xb4, 0x19, 0xe2, 0x40, 0xe9, 0x7f, + 0x55, 0x70, 0x7f, 0x52, 0xe9, 0xcf, 0x56, 0x84, 0xfe, 0x9c, 0x9b, 0x80, 0xf3, 0x74, 0xe6, 0xf3, + 0x06, 0x28, 0x79, 0xd3, 0x4d, 0x77, 0x2d, 0xcb, 0xbf, 0xcb, 0x81, 0x72, 0x60, 0x8a, 0x29, 0x2f, + 0xf5, 0x7b, 0xa1, 0x4a, 0xc6, 0xee, 0x98, 0xb5, 0x2c, 0x0b, 0x69, 0xb8, 0x55, 0xeb, 0x6d, 0x9d, + 0x5a, 0xc1, 0x37, 0xe8, 0x78, 0x31, 0x7b, 0x13, 0x2c, 0x50, 0x6c, 0xf5, 0x09, 0x75, 0x65, 0x7c, + 0xc3, 0x4a, 0x7e, 0x47, 0xe9, 0x4e, 0x48, 0x8a, 0x22, 0xda, 0xa7, 0xae, 0x83, 0xf9, 0xd0, 0x64, + 0xf0, 0x04, 0xc8, 0x3f, 0x20, 0x43, 0x87, 0x0c, 0x22, 0xf6, 0x13, 0x2e, 0x83, 0xc2, 0x01, 0x56, + 0x07, 0x4e, 0x88, 0x96, 0x90, 0xf3, 0x70, 0x2d, 0xf7, 0xba, 0x24, 0xff, 0x86, 0x6d, 0x8e, 0x9f, + 0x0a, 0x47, 0x10, 0x5d, 0xef, 0x84, 0xa2, 0x2b, 0xfd, 0x5f, 0xd3, 0x60, 0x82, 0xa6, 0xc5, 0x18, + 0x8a, 0xc4, 0xd8, 0x4b, 0x99, 0xd0, 0x9e, 0x1e, 0x69, 0xff, 0xca, 0x81, 0xe5, 0x80, 0xb6, 0x4f, + 0xb2, 0xbf, 0x1f, 0x22, 0xd9, 0xab, 0x11, 0x92, 0x5d, 0x4d, 0xb2, 0xf9, 0x96, 0x65, 0x4f, 0x66, + 0xd9, 0x7f, 0x96, 0xc0, 0x62, 0x60, 0xef, 0x8e, 0x80, 0x66, 0xdf, 0x0a, 0xd3, 0xec, 0x73, 0x59, + 0x82, 0x26, 0x85, 0x67, 0x5f, 0x03, 0x4b, 0x01, 0xa5, 0xdb, 0x56, 0x4f, 0xd1, 0xb1, 0x6a, 0xc3, + 0xb3, 0xa0, 0x60, 0x53, 0x6c, 0x51, 0xb7, 0x88, 0xb8, 0xb6, 0x1d, 0x36, 0x88, 0x1c, 0x99, 0xfc, + 0x6f, 0x09, 0x34, 0x03, 0xc6, 0x6d, 0x62, 0xd9, 0x8a, 0x4d, 0x89, 0x4e, 0xef, 0x1a, 0xea, 0x40, + 0x23, 0x1b, 0x2a, 0x56, 0x34, 0x44, 0xd8, 0x80, 0x62, 0xe8, 0x6d, 0x43, 0x55, 0xba, 0x43, 0x88, + 0x41, 0xf9, 0xc3, 0x7d, 0xa2, 0x6f, 0x12, 0x95, 0x50, 0xf1, 0xbf, 0x60, 0xa9, 0xf5, 0x96, 0xfb, + 0x37, 0xd9, 0x7b, 0xbe, 0xe8, 0xc9, 0xa8, 0xbe, 0x9a, 0x05, 0x91, 0x47, 0x68, 0x10, 0x13, 0xfe, + 0x14, 0x00, 0xf6, 0xc8, 0xef, 0xb2, 0x9e, 0x08, 0xd6, 0x37, 0xdd, 0x8c, 0x7e, 0xcf, 0x93, 0x4c, + 0x35, 0x41, 0x00, 0x51, 0xfe, 0x43, 0x31, 0x74, 0xde, 0xdf, 0xf8, 0xde, 0xeb, 0xcf, 0xc1, 0xf2, + 0x81, 0xbf, 0x3b, 0xae, 0x02, 0xa3, 0xf2, 0xf9, 0x68, 0x53, 0xc0, 0x83, 0x4f, 0xda, 0x57, 0xff, + 0x05, 0xe2, 0x6e, 0x02, 0x1c, 0x4a, 0x9c, 0x04, 0xbe, 0x0a, 0xca, 0x8c, 0x37, 0x2b, 0x5d, 0xb2, + 0x83, 0x35, 0x37, 0x17, 0xbd, 0xbf, 0x55, 0x3b, 0xbe, 0x08, 0x05, 0xf5, 0xe0, 0x3e, 0x58, 0x32, + 0x8d, 0xde, 0x36, 0xd6, 0x71, 0x9f, 0x30, 0x22, 0xe8, 0x1c, 0x25, 0x6f, 0xc8, 0x96, 0x5a, 0xaf, + 0xb9, 0xcd, 0xb6, 0x76, 0x5c, 0xe5, 0xc9, 0xa8, 0x5e, 0x49, 0x18, 0xe6, 0x41, 0x90, 0x04, 0x09, + 0xad, 0xd8, 0xa7, 0x00, 0xce, 0x5f, 0x21, 0x6b, 0x59, 0x92, 0xf2, 0x90, 0x1f, 0x03, 0xa4, 0xf5, + 0x9b, 0x8b, 0x87, 0xea, 0x37, 0x27, 0xbc, 0x2d, 0x97, 0xa6, 0x7c, 0x5b, 0xfe, 0xab, 0x04, 0xce, + 0x99, 0x19, 0x72, 0xa9, 0x0a, 0xf8, 0xde, 0xdc, 0xcc, 0xb2, 0x37, 0x59, 0x72, 0xb3, 0xb5, 0x3a, + 0x1e, 0xd5, 0xcf, 0x65, 0xd1, 0x44, 0x99, 0xfc, 0x83, 0x77, 0x41, 0xd1, 0x10, 0x77, 0x60, 0xb5, + 0xcc, 0x7d, 0xbd, 0x94, 0xc5, 0x57, 0xf7, 0xde, 0x74, 0xd2, 0xd2, 0x7d, 0x42, 0x1e, 0x96, 0xfc, + 0x71, 0x01, 0x9c, 0x8c, 0x55, 0xf0, 0xaf, 0xb0, 0xab, 0x1e, 0x7b, 0x2f, 0xcf, 0x4f, 0xf1, 0x5e, + 0xbe, 0x0e, 0x16, 0xc5, 0x87, 0x1a, 0x91, 0xd7, 0x7a, 0x2f, 0x60, 0x36, 0xc2, 0x62, 0x14, 0xd5, + 0x4f, 0xea, 0xea, 0x17, 0xa6, 0xec, 0xea, 0x07, 0xbd, 0x10, 0x1f, 0x1e, 0x3a, 0xe9, 0x1d, 0xf7, + 0x42, 0x7c, 0x7f, 0x18, 0xd5, 0x67, 0xc4, 0xd5, 0x41, 0xf5, 0x10, 0xe6, 0xc2, 0xc4, 0x75, 0x37, + 0x24, 0x45, 0x11, 0xed, 0x2f, 0xf5, 0x31, 0x02, 0x4e, 0xf8, 0x18, 0xe1, 0x72, 0x96, 0x58, 0xcb, + 0xde, 0x75, 0x4f, 0xec, 0x9f, 0x94, 0xa7, 0xef, 0x9f, 0xc8, 0x7f, 0x93, 0xc0, 0x0b, 0xa9, 0xb7, + 0x16, 0x5c, 0x0f, 0xd1, 0xca, 0xcb, 0x11, 0x5a, 0xf9, 0xbd, 0x54, 0xc3, 0x00, 0xb7, 0xb4, 0x92, + 0x1b, 0xf2, 0x6f, 0x64, 0x6b, 0xc8, 0x27, 0xbc, 0x09, 0x4f, 0xee, 0xcc, 0xb7, 0x7e, 0xf0, 0xe8, + 0x71, 0xed, 0xd8, 0xa7, 0x8f, 0x6b, 0xc7, 0x3e, 0x7f, 0x5c, 0x3b, 0xf6, 0x8b, 0x71, 0x4d, 0x7a, + 0x34, 0xae, 0x49, 0x9f, 0x8e, 0x6b, 0xd2, 0xe7, 0xe3, 0x9a, 0xf4, 0xf7, 0x71, 0x4d, 0xfa, 0xed, + 0x17, 0xb5, 0x63, 0xef, 0x57, 0x52, 0x3e, 0x85, 0xfe, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd4, + 0x01, 0x82, 0xf5, 0x24, 0x2d, 0x00, 0x00, } func (m *ControllerRevision) Marshal() (dAtA []byte, err error) { @@ -1845,6 +1847,11 @@ func (m *DeploymentStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.TerminatingReplicas != nil { + i = encodeVarintGenerated(dAtA, i, uint64(*m.TerminatingReplicas)) + i-- + dAtA[i] = 0x48 + } if m.CollisionCount != nil { i = encodeVarintGenerated(dAtA, i, uint64(*m.CollisionCount)) i-- @@ -2151,6 +2158,11 @@ func (m *ReplicaSetStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.TerminatingReplicas != nil { + i = encodeVarintGenerated(dAtA, i, uint64(*m.TerminatingReplicas)) + i-- + dAtA[i] = 0x38 + } if len(m.Conditions) > 0 { for iNdEx := len(m.Conditions) - 1; iNdEx >= 0; iNdEx-- { { @@ -3146,6 +3158,9 @@ func (m *DeploymentStatus) Size() (n int) { if m.CollisionCount != nil { n += 1 + sovGenerated(uint64(*m.CollisionCount)) } + if m.TerminatingReplicas != nil { + n += 1 + sovGenerated(uint64(*m.TerminatingReplicas)) + } return n } @@ -3251,6 +3266,9 @@ func (m *ReplicaSetStatus) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) } } + if m.TerminatingReplicas != nil { + n += 1 + sovGenerated(uint64(*m.TerminatingReplicas)) + } return n } @@ -3711,6 +3729,7 @@ func (this *DeploymentStatus) String() string { `Conditions:` + repeatedStringForConditions + `,`, `ReadyReplicas:` + fmt.Sprintf("%v", this.ReadyReplicas) + `,`, `CollisionCount:` + valueToStringGenerated(this.CollisionCount) + `,`, + `TerminatingReplicas:` + valueToStringGenerated(this.TerminatingReplicas) + `,`, `}`, }, "") return s @@ -3797,6 +3816,7 @@ func (this *ReplicaSetStatus) String() string { `ReadyReplicas:` + fmt.Sprintf("%v", this.ReadyReplicas) + `,`, `AvailableReplicas:` + fmt.Sprintf("%v", this.AvailableReplicas) + `,`, `Conditions:` + repeatedStringForConditions + `,`, + `TerminatingReplicas:` + valueToStringGenerated(this.TerminatingReplicas) + `,`, `}`, }, "") return s @@ -6261,6 +6281,26 @@ func (m *DeploymentStatus) Unmarshal(dAtA []byte) error { } } m.CollisionCount = &v + case 9: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TerminatingReplicas", wireType) + } + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.TerminatingReplicas = &v default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -7193,6 +7233,26 @@ func (m *ReplicaSetStatus) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TerminatingReplicas", wireType) + } + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.TerminatingReplicas = &v default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/go-controller/vendor/k8s.io/api/apps/v1beta2/generated.proto b/go-controller/vendor/k8s.io/api/apps/v1beta2/generated.proto index c08a4c78bc..68c463e257 100644 --- a/go-controller/vendor/k8s.io/api/apps/v1beta2/generated.proto +++ b/go-controller/vendor/k8s.io/api/apps/v1beta2/generated.proto @@ -323,19 +323,19 @@ message DeploymentStatus { // +optional optional int64 observedGeneration = 1; - // Total number of non-terminated pods targeted by this deployment (their labels match the selector). + // Total number of non-terminating pods targeted by this deployment (their labels match the selector). // +optional optional int32 replicas = 2; - // Total number of non-terminated pods targeted by this deployment that have the desired template spec. + // Total number of non-terminating pods targeted by this deployment that have the desired template spec. // +optional optional int32 updatedReplicas = 3; - // readyReplicas is the number of pods targeted by this Deployment controller with a Ready Condition. + // Total number of non-terminating pods targeted by this Deployment with a Ready Condition. // +optional optional int32 readyReplicas = 7; - // Total number of available pods (ready for at least minReadySeconds) targeted by this deployment. + // Total number of available non-terminating pods (ready for at least minReadySeconds) targeted by this deployment. // +optional optional int32 availableReplicas = 4; @@ -345,6 +345,13 @@ message DeploymentStatus { // +optional optional int32 unavailableReplicas = 5; + // Total number of terminating pods targeted by this deployment. Terminating pods have a non-null + // .metadata.deletionTimestamp and have not yet reached the Failed or Succeeded .status.phase. + // + // This is an alpha field. Enable DeploymentReplicaSetTerminatingReplicas to be able to use this field. + // +optional + optional int32 terminatingReplicas = 9; + // Represents the latest available observations of a deployment's current state. // +patchMergeKey=type // +patchStrategy=merge @@ -427,16 +434,16 @@ message ReplicaSetList { optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; // List of ReplicaSets. - // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller + // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset repeated ReplicaSet items = 2; } // ReplicaSetSpec is the specification of a ReplicaSet. message ReplicaSetSpec { - // Replicas is the number of desired replicas. + // Replicas is the number of desired pods. // This is a pointer to distinguish between explicit zero and unspecified. // Defaults to 1. - // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller + // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset // +optional optional int32 replicas = 1; @@ -454,29 +461,36 @@ message ReplicaSetSpec { // Template is the object that describes the pod that will be created if // insufficient replicas are detected. - // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template + // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/#pod-template // +optional optional .k8s.io.api.core.v1.PodTemplateSpec template = 3; } // ReplicaSetStatus represents the current status of a ReplicaSet. message ReplicaSetStatus { - // Replicas is the most recently observed number of replicas. - // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller + // Replicas is the most recently observed number of non-terminating pods. + // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset optional int32 replicas = 1; - // The number of pods that have labels matching the labels of the pod template of the replicaset. + // The number of non-terminating pods that have labels matching the labels of the pod template of the replicaset. // +optional optional int32 fullyLabeledReplicas = 2; - // readyReplicas is the number of pods targeted by this ReplicaSet controller with a Ready Condition. + // The number of non-terminating pods targeted by this ReplicaSet with a Ready Condition. // +optional optional int32 readyReplicas = 4; - // The number of available replicas (ready for at least minReadySeconds) for this replica set. + // The number of available non-terminating pods (ready for at least minReadySeconds) for this replica set. // +optional optional int32 availableReplicas = 5; + // The number of terminating pods for this replica set. Terminating pods have a non-null .metadata.deletionTimestamp + // and have not yet reached the Failed or Succeeded .status.phase. + // + // This is an alpha field. Enable DeploymentReplicaSetTerminatingReplicas to be able to use this field. + // +optional + optional int32 terminatingReplicas = 7; + // ObservedGeneration reflects the generation of the most recently observed ReplicaSet. // +optional optional int64 observedGeneration = 3; @@ -747,6 +761,7 @@ message StatefulSetSpec { // the network identity of the set. Pods get DNS/hostnames that follow the // pattern: pod-specific-string.serviceName.default.svc.cluster.local // where "pod-specific-string" is managed by the StatefulSet controller. + // +optional optional string serviceName = 5; // podManagementPolicy controls how pods are created during initial scale up, diff --git a/go-controller/vendor/k8s.io/api/apps/v1beta2/types.go b/go-controller/vendor/k8s.io/api/apps/v1beta2/types.go index c2624a941d..491afc59f5 100644 --- a/go-controller/vendor/k8s.io/api/apps/v1beta2/types.go +++ b/go-controller/vendor/k8s.io/api/apps/v1beta2/types.go @@ -269,6 +269,7 @@ type StatefulSetSpec struct { // the network identity of the set. Pods get DNS/hostnames that follow the // pattern: pod-specific-string.serviceName.default.svc.cluster.local // where "pod-specific-string" is managed by the StatefulSet controller. + // +optional ServiceName string `json:"serviceName" protobuf:"bytes,5,opt,name=serviceName"` // podManagementPolicy controls how pods are created during initial scale up, @@ -530,19 +531,19 @@ type DeploymentStatus struct { // +optional ObservedGeneration int64 `json:"observedGeneration,omitempty" protobuf:"varint,1,opt,name=observedGeneration"` - // Total number of non-terminated pods targeted by this deployment (their labels match the selector). + // Total number of non-terminating pods targeted by this deployment (their labels match the selector). // +optional Replicas int32 `json:"replicas,omitempty" protobuf:"varint,2,opt,name=replicas"` - // Total number of non-terminated pods targeted by this deployment that have the desired template spec. + // Total number of non-terminating pods targeted by this deployment that have the desired template spec. // +optional UpdatedReplicas int32 `json:"updatedReplicas,omitempty" protobuf:"varint,3,opt,name=updatedReplicas"` - // readyReplicas is the number of pods targeted by this Deployment controller with a Ready Condition. + // Total number of non-terminating pods targeted by this Deployment with a Ready Condition. // +optional ReadyReplicas int32 `json:"readyReplicas,omitempty" protobuf:"varint,7,opt,name=readyReplicas"` - // Total number of available pods (ready for at least minReadySeconds) targeted by this deployment. + // Total number of available non-terminating pods (ready for at least minReadySeconds) targeted by this deployment. // +optional AvailableReplicas int32 `json:"availableReplicas,omitempty" protobuf:"varint,4,opt,name=availableReplicas"` @@ -552,6 +553,13 @@ type DeploymentStatus struct { // +optional UnavailableReplicas int32 `json:"unavailableReplicas,omitempty" protobuf:"varint,5,opt,name=unavailableReplicas"` + // Total number of terminating pods targeted by this deployment. Terminating pods have a non-null + // .metadata.deletionTimestamp and have not yet reached the Failed or Succeeded .status.phase. + // + // This is an alpha field. Enable DeploymentReplicaSetTerminatingReplicas to be able to use this field. + // +optional + TerminatingReplicas *int32 `json:"terminatingReplicas,omitempty" protobuf:"varint,9,opt,name=terminatingReplicas"` + // Represents the latest available observations of a deployment's current state. // +patchMergeKey=type // +patchStrategy=merge @@ -897,16 +905,16 @@ type ReplicaSetList struct { metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` // List of ReplicaSets. - // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller + // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset Items []ReplicaSet `json:"items" protobuf:"bytes,2,rep,name=items"` } // ReplicaSetSpec is the specification of a ReplicaSet. type ReplicaSetSpec struct { - // Replicas is the number of desired replicas. + // Replicas is the number of desired pods. // This is a pointer to distinguish between explicit zero and unspecified. // Defaults to 1. - // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller + // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset // +optional Replicas *int32 `json:"replicas,omitempty" protobuf:"varint,1,opt,name=replicas"` @@ -924,29 +932,36 @@ type ReplicaSetSpec struct { // Template is the object that describes the pod that will be created if // insufficient replicas are detected. - // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template + // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/#pod-template // +optional Template v1.PodTemplateSpec `json:"template,omitempty" protobuf:"bytes,3,opt,name=template"` } // ReplicaSetStatus represents the current status of a ReplicaSet. type ReplicaSetStatus struct { - // Replicas is the most recently observed number of replicas. - // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller + // Replicas is the most recently observed number of non-terminating pods. + // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset Replicas int32 `json:"replicas" protobuf:"varint,1,opt,name=replicas"` - // The number of pods that have labels matching the labels of the pod template of the replicaset. + // The number of non-terminating pods that have labels matching the labels of the pod template of the replicaset. // +optional FullyLabeledReplicas int32 `json:"fullyLabeledReplicas,omitempty" protobuf:"varint,2,opt,name=fullyLabeledReplicas"` - // readyReplicas is the number of pods targeted by this ReplicaSet controller with a Ready Condition. + // The number of non-terminating pods targeted by this ReplicaSet with a Ready Condition. // +optional ReadyReplicas int32 `json:"readyReplicas,omitempty" protobuf:"varint,4,opt,name=readyReplicas"` - // The number of available replicas (ready for at least minReadySeconds) for this replica set. + // The number of available non-terminating pods (ready for at least minReadySeconds) for this replica set. // +optional AvailableReplicas int32 `json:"availableReplicas,omitempty" protobuf:"varint,5,opt,name=availableReplicas"` + // The number of terminating pods for this replica set. Terminating pods have a non-null .metadata.deletionTimestamp + // and have not yet reached the Failed or Succeeded .status.phase. + // + // This is an alpha field. Enable DeploymentReplicaSetTerminatingReplicas to be able to use this field. + // +optional + TerminatingReplicas *int32 `json:"terminatingReplicas,omitempty" protobuf:"varint,7,opt,name=terminatingReplicas"` + // ObservedGeneration reflects the generation of the most recently observed ReplicaSet. // +optional ObservedGeneration int64 `json:"observedGeneration,omitempty" protobuf:"varint,3,opt,name=observedGeneration"` diff --git a/go-controller/vendor/k8s.io/api/apps/v1beta2/types_swagger_doc_generated.go b/go-controller/vendor/k8s.io/api/apps/v1beta2/types_swagger_doc_generated.go index beec4b7555..4089434151 100644 --- a/go-controller/vendor/k8s.io/api/apps/v1beta2/types_swagger_doc_generated.go +++ b/go-controller/vendor/k8s.io/api/apps/v1beta2/types_swagger_doc_generated.go @@ -177,11 +177,12 @@ func (DeploymentSpec) SwaggerDoc() map[string]string { var map_DeploymentStatus = map[string]string{ "": "DeploymentStatus is the most recently observed status of the Deployment.", "observedGeneration": "The generation observed by the deployment controller.", - "replicas": "Total number of non-terminated pods targeted by this deployment (their labels match the selector).", - "updatedReplicas": "Total number of non-terminated pods targeted by this deployment that have the desired template spec.", - "readyReplicas": "readyReplicas is the number of pods targeted by this Deployment controller with a Ready Condition.", - "availableReplicas": "Total number of available pods (ready for at least minReadySeconds) targeted by this deployment.", + "replicas": "Total number of non-terminating pods targeted by this deployment (their labels match the selector).", + "updatedReplicas": "Total number of non-terminating pods targeted by this deployment that have the desired template spec.", + "readyReplicas": "Total number of non-terminating pods targeted by this Deployment with a Ready Condition.", + "availableReplicas": "Total number of available non-terminating pods (ready for at least minReadySeconds) targeted by this deployment.", "unavailableReplicas": "Total number of unavailable pods targeted by this deployment. This is the total number of pods that are still required for the deployment to have 100% available capacity. They may either be pods that are running but not yet available or pods that still have not been created.", + "terminatingReplicas": "Total number of terminating pods targeted by this deployment. Terminating pods have a non-null .metadata.deletionTimestamp and have not yet reached the Failed or Succeeded .status.phase.\n\nThis is an alpha field. Enable DeploymentReplicaSetTerminatingReplicas to be able to use this field.", "conditions": "Represents the latest available observations of a deployment's current state.", "collisionCount": "Count of hash collisions for the Deployment. The Deployment controller uses this field as a collision avoidance mechanism when it needs to create the name for the newest ReplicaSet.", } @@ -227,7 +228,7 @@ func (ReplicaSetCondition) SwaggerDoc() map[string]string { var map_ReplicaSetList = map[string]string{ "": "ReplicaSetList is a collection of ReplicaSets.", "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "items": "List of ReplicaSets. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller", + "items": "List of ReplicaSets. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset", } func (ReplicaSetList) SwaggerDoc() map[string]string { @@ -236,10 +237,10 @@ func (ReplicaSetList) SwaggerDoc() map[string]string { var map_ReplicaSetSpec = map[string]string{ "": "ReplicaSetSpec is the specification of a ReplicaSet.", - "replicas": "Replicas is the number of desired replicas. This is a pointer to distinguish between explicit zero and unspecified. Defaults to 1. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller", + "replicas": "Replicas is the number of desired pods. This is a pointer to distinguish between explicit zero and unspecified. Defaults to 1. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset", "minReadySeconds": "Minimum number of seconds for which a newly created pod should be ready without any of its container crashing, for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready)", "selector": "Selector is a label query over pods that should match the replica count. Label keys and values that must match in order to be controlled by this replica set. It must match the pod template's labels. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors", - "template": "Template is the object that describes the pod that will be created if insufficient replicas are detected. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template", + "template": "Template is the object that describes the pod that will be created if insufficient replicas are detected. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/#pod-template", } func (ReplicaSetSpec) SwaggerDoc() map[string]string { @@ -248,10 +249,11 @@ func (ReplicaSetSpec) SwaggerDoc() map[string]string { var map_ReplicaSetStatus = map[string]string{ "": "ReplicaSetStatus represents the current status of a ReplicaSet.", - "replicas": "Replicas is the most recently observed number of replicas. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller", - "fullyLabeledReplicas": "The number of pods that have labels matching the labels of the pod template of the replicaset.", - "readyReplicas": "readyReplicas is the number of pods targeted by this ReplicaSet controller with a Ready Condition.", - "availableReplicas": "The number of available replicas (ready for at least minReadySeconds) for this replica set.", + "replicas": "Replicas is the most recently observed number of non-terminating pods. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset", + "fullyLabeledReplicas": "The number of non-terminating pods that have labels matching the labels of the pod template of the replicaset.", + "readyReplicas": "The number of non-terminating pods targeted by this ReplicaSet with a Ready Condition.", + "availableReplicas": "The number of available non-terminating pods (ready for at least minReadySeconds) for this replica set.", + "terminatingReplicas": "The number of terminating pods for this replica set. Terminating pods have a non-null .metadata.deletionTimestamp and have not yet reached the Failed or Succeeded .status.phase.\n\nThis is an alpha field. Enable DeploymentReplicaSetTerminatingReplicas to be able to use this field.", "observedGeneration": "ObservedGeneration reflects the generation of the most recently observed ReplicaSet.", "conditions": "Represents the latest available observations of a replica set's current state.", } diff --git a/go-controller/vendor/k8s.io/api/apps/v1beta2/zz_generated.deepcopy.go b/go-controller/vendor/k8s.io/api/apps/v1beta2/zz_generated.deepcopy.go index cd92792db5..917ad4a22f 100644 --- a/go-controller/vendor/k8s.io/api/apps/v1beta2/zz_generated.deepcopy.go +++ b/go-controller/vendor/k8s.io/api/apps/v1beta2/zz_generated.deepcopy.go @@ -363,6 +363,11 @@ func (in *DeploymentSpec) DeepCopy() *DeploymentSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DeploymentStatus) DeepCopyInto(out *DeploymentStatus) { *out = *in + if in.TerminatingReplicas != nil { + in, out := &in.TerminatingReplicas, &out.TerminatingReplicas + *out = new(int32) + **out = **in + } if in.Conditions != nil { in, out := &in.Conditions, &out.Conditions *out = make([]DeploymentCondition, len(*in)) @@ -517,6 +522,11 @@ func (in *ReplicaSetSpec) DeepCopy() *ReplicaSetSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ReplicaSetStatus) DeepCopyInto(out *ReplicaSetStatus) { *out = *in + if in.TerminatingReplicas != nil { + in, out := &in.TerminatingReplicas, &out.TerminatingReplicas + *out = new(int32) + **out = **in + } if in.Conditions != nil { in, out := &in.Conditions, &out.Conditions *out = make([]ReplicaSetCondition, len(*in)) diff --git a/go-controller/vendor/k8s.io/api/authentication/v1/doc.go b/go-controller/vendor/k8s.io/api/authentication/v1/doc.go index 3bdc89badc..dc3aed4e4f 100644 --- a/go-controller/vendor/k8s.io/api/authentication/v1/doc.go +++ b/go-controller/vendor/k8s.io/api/authentication/v1/doc.go @@ -20,4 +20,4 @@ limitations under the License. // +k8s:openapi-gen=true // +k8s:prerelease-lifecycle-gen=true -package v1 // import "k8s.io/api/authentication/v1" +package v1 diff --git a/go-controller/vendor/k8s.io/api/authentication/v1alpha1/doc.go b/go-controller/vendor/k8s.io/api/authentication/v1alpha1/doc.go index eb32def904..c199ccd499 100644 --- a/go-controller/vendor/k8s.io/api/authentication/v1alpha1/doc.go +++ b/go-controller/vendor/k8s.io/api/authentication/v1alpha1/doc.go @@ -20,4 +20,4 @@ limitations under the License. // +k8s:openapi-gen=true // +k8s:prerelease-lifecycle-gen=true -package v1alpha1 // import "k8s.io/api/authentication/v1alpha1" +package v1alpha1 diff --git a/go-controller/vendor/k8s.io/api/authentication/v1beta1/doc.go b/go-controller/vendor/k8s.io/api/authentication/v1beta1/doc.go index 2a2b176e43..af63dc845b 100644 --- a/go-controller/vendor/k8s.io/api/authentication/v1beta1/doc.go +++ b/go-controller/vendor/k8s.io/api/authentication/v1beta1/doc.go @@ -20,4 +20,4 @@ limitations under the License. // +k8s:openapi-gen=true // +k8s:prerelease-lifecycle-gen=true -package v1beta1 // import "k8s.io/api/authentication/v1beta1" +package v1beta1 diff --git a/go-controller/vendor/k8s.io/api/authorization/v1/doc.go b/go-controller/vendor/k8s.io/api/authorization/v1/doc.go index 77e5a19c4c..40bf8006e0 100644 --- a/go-controller/vendor/k8s.io/api/authorization/v1/doc.go +++ b/go-controller/vendor/k8s.io/api/authorization/v1/doc.go @@ -20,4 +20,4 @@ limitations under the License. // +k8s:prerelease-lifecycle-gen=true // +groupName=authorization.k8s.io -package v1 // import "k8s.io/api/authorization/v1" +package v1 diff --git a/go-controller/vendor/k8s.io/api/authorization/v1beta1/doc.go b/go-controller/vendor/k8s.io/api/authorization/v1beta1/doc.go index c996e35ccc..9f7332d493 100644 --- a/go-controller/vendor/k8s.io/api/authorization/v1beta1/doc.go +++ b/go-controller/vendor/k8s.io/api/authorization/v1beta1/doc.go @@ -21,4 +21,4 @@ limitations under the License. // +groupName=authorization.k8s.io -package v1beta1 // import "k8s.io/api/authorization/v1beta1" +package v1beta1 diff --git a/go-controller/vendor/k8s.io/api/autoscaling/v1/doc.go b/go-controller/vendor/k8s.io/api/autoscaling/v1/doc.go index d64c9cbc1a..4ee085e165 100644 --- a/go-controller/vendor/k8s.io/api/autoscaling/v1/doc.go +++ b/go-controller/vendor/k8s.io/api/autoscaling/v1/doc.go @@ -19,4 +19,4 @@ limitations under the License. // +k8s:openapi-gen=true // +k8s:prerelease-lifecycle-gen=true -package v1 // import "k8s.io/api/autoscaling/v1" +package v1 diff --git a/go-controller/vendor/k8s.io/api/autoscaling/v2/doc.go b/go-controller/vendor/k8s.io/api/autoscaling/v2/doc.go index aafa2d4de2..8dea6339df 100644 --- a/go-controller/vendor/k8s.io/api/autoscaling/v2/doc.go +++ b/go-controller/vendor/k8s.io/api/autoscaling/v2/doc.go @@ -19,4 +19,4 @@ limitations under the License. // +k8s:openapi-gen=true // +k8s:prerelease-lifecycle-gen=true -package v2 // import "k8s.io/api/autoscaling/v2" +package v2 diff --git a/go-controller/vendor/k8s.io/api/autoscaling/v2/generated.pb.go b/go-controller/vendor/k8s.io/api/autoscaling/v2/generated.pb.go index ece6dedadb..40b60ebeca 100644 --- a/go-controller/vendor/k8s.io/api/autoscaling/v2/generated.pb.go +++ b/go-controller/vendor/k8s.io/api/autoscaling/v2/generated.pb.go @@ -751,115 +751,116 @@ func init() { } var fileDescriptor_4d5f2c8767749221 = []byte{ - // 1722 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x59, 0xcb, 0x8f, 0x1b, 0x49, - 0x19, 0x9f, 0xb6, 0x3d, 0xaf, 0xf2, 0x3c, 0x2b, 0x2f, 0x67, 0xa2, 0xd8, 0xa3, 0x26, 0x90, 0x07, - 0xa4, 0x4d, 0x4c, 0x88, 0x22, 0x72, 0x40, 0xd3, 0x13, 0x20, 0xa3, 0xcc, 0x30, 0x4e, 0x39, 0xc9, - 0x00, 0x02, 0x94, 0x72, 0x77, 0x8d, 0xa7, 0x18, 0xbb, 0xdb, 0xea, 0x6e, 0x3b, 0x99, 0x48, 0x48, - 0x5c, 0xb8, 0x23, 0x50, 0x84, 0xf8, 0x1f, 0x22, 0x4e, 0xa0, 0x70, 0x00, 0x09, 0x69, 0xf7, 0x90, - 0xcb, 0x4a, 0x39, 0xec, 0x21, 0x27, 0x6b, 0xe3, 0x95, 0xf6, 0xb8, 0x7f, 0x40, 0x4e, 0xab, 0x7a, - 0xf4, 0xd3, 0xaf, 0x71, 0x76, 0x32, 0xd2, 0xdc, 0x5c, 0x55, 0xdf, 0xf7, 0xfb, 0x1e, 0xf5, 0xbd, - 0xaa, 0x0d, 0xae, 0xee, 0xdf, 0x76, 0x35, 0x6a, 0x17, 0x71, 0x93, 0x16, 0x71, 0xcb, 0xb3, 0x5d, - 0x03, 0xd7, 0xa9, 0x55, 0x2b, 0xb6, 0x4b, 0xc5, 0x1a, 0xb1, 0x88, 0x83, 0x3d, 0x62, 0x6a, 0x4d, - 0xc7, 0xf6, 0x6c, 0x78, 0x5e, 0x90, 0x6a, 0xb8, 0x49, 0xb5, 0x08, 0xa9, 0xd6, 0x2e, 0xad, 0x5c, - 0xaf, 0x51, 0x6f, 0xaf, 0x55, 0xd5, 0x0c, 0xbb, 0x51, 0xac, 0xd9, 0x35, 0xbb, 0xc8, 0x39, 0xaa, - 0xad, 0x5d, 0xbe, 0xe2, 0x0b, 0xfe, 0x4b, 0x20, 0xad, 0xa8, 0x11, 0xa1, 0x86, 0xed, 0x90, 0x62, - 0xfb, 0x46, 0x52, 0xda, 0xca, 0xcd, 0x90, 0xa6, 0x81, 0x8d, 0x3d, 0x6a, 0x11, 0xe7, 0xa0, 0xd8, - 0xdc, 0xaf, 0x71, 0x26, 0x87, 0xb8, 0x76, 0xcb, 0x31, 0xc8, 0x58, 0x5c, 0x6e, 0xb1, 0x41, 0x3c, - 0xdc, 0x4f, 0x56, 0x71, 0x10, 0x97, 0xd3, 0xb2, 0x3c, 0xda, 0xe8, 0x15, 0x73, 0x6b, 0x14, 0x83, - 0x6b, 0xec, 0x91, 0x06, 0x4e, 0xf2, 0xa9, 0x5f, 0x29, 0xe0, 0xe2, 0xba, 0x6d, 0x79, 0x98, 0x71, - 0x20, 0x69, 0xc4, 0x16, 0xf1, 0x1c, 0x6a, 0x54, 0xf8, 0x6f, 0xb8, 0x0e, 0x32, 0x16, 0x6e, 0x90, - 0x9c, 0xb2, 0xaa, 0x5c, 0x99, 0xd5, 0x8b, 0xaf, 0x3b, 0x85, 0x89, 0x6e, 0xa7, 0x90, 0xf9, 0x25, - 0x6e, 0x90, 0xf7, 0x9d, 0x42, 0xa1, 0xd7, 0x71, 0x9a, 0x0f, 0xc3, 0x48, 0x10, 0x67, 0x86, 0xdb, - 0x60, 0xca, 0xc3, 0x4e, 0x8d, 0x78, 0xb9, 0xd4, 0xaa, 0x72, 0x25, 0x5b, 0xba, 0xac, 0x0d, 0xbc, - 0x3a, 0x4d, 0x48, 0x7f, 0xc8, 0xc9, 0xf5, 0x05, 0x29, 0x6f, 0x4a, 0xac, 0x91, 0x84, 0x81, 0x45, - 0x30, 0x6b, 0xf8, 0x6a, 0xe7, 0xd2, 0x5c, 0xb5, 0x65, 0x49, 0x3a, 0x1b, 0xda, 0x13, 0xd2, 0xa8, - 0x5f, 0x0f, 0x31, 0xd4, 0xc3, 0x5e, 0xcb, 0x3d, 0x1a, 0x43, 0x77, 0xc0, 0xb4, 0xd1, 0x72, 0x1c, - 0x62, 0xf9, 0x96, 0xfe, 0x60, 0xa4, 0xa5, 0x8f, 0x71, 0xbd, 0x45, 0x84, 0x0e, 0xfa, 0xa2, 0x94, - 0x3a, 0xbd, 0x2e, 0x40, 0x90, 0x8f, 0x36, 0xbe, 0xc1, 0x2f, 0x14, 0x70, 0x61, 0xdd, 0xb1, 0x5d, - 0xf7, 0x31, 0x71, 0x5c, 0x6a, 0x5b, 0xdb, 0xd5, 0x3f, 0x10, 0xc3, 0x43, 0x64, 0x97, 0x38, 0xc4, - 0x32, 0x08, 0x5c, 0x05, 0x99, 0x7d, 0x6a, 0x99, 0xd2, 0xdc, 0x39, 0xdf, 0xdc, 0xfb, 0xd4, 0x32, - 0x11, 0x3f, 0x61, 0x14, 0xdc, 0x21, 0xa9, 0x38, 0x45, 0xc4, 0xda, 0x12, 0x00, 0xb8, 0x49, 0xa5, - 0x00, 0xa9, 0x15, 0x94, 0x74, 0x60, 0xad, 0xbc, 0x21, 0x4f, 0x50, 0x84, 0x4a, 0xfd, 0xaf, 0x02, - 0x4e, 0xff, 0xec, 0x99, 0x47, 0x1c, 0x0b, 0xd7, 0x63, 0x81, 0x56, 0x01, 0x53, 0x0d, 0xbe, 0xe6, - 0x2a, 0x65, 0x4b, 0xdf, 0x1f, 0xe9, 0xb9, 0x0d, 0x93, 0x58, 0x1e, 0xdd, 0xa5, 0xc4, 0x09, 0xe3, - 0x44, 0x9c, 0x20, 0x09, 0x75, 0xe4, 0x81, 0xa7, 0x7e, 0xda, 0xab, 0xbe, 0x08, 0x9f, 0x8f, 0xa2, - 0xfe, 0xc7, 0x0a, 0x27, 0xf5, 0x9f, 0x0a, 0x58, 0xba, 0x57, 0x5e, 0xab, 0x08, 0xee, 0xb2, 0x5d, - 0xa7, 0xc6, 0x01, 0xbc, 0x0d, 0x32, 0xde, 0x41, 0xd3, 0xcf, 0x80, 0x4b, 0xfe, 0x85, 0x3f, 0x3c, - 0x68, 0xb2, 0x0c, 0x38, 0x9d, 0xa4, 0x67, 0xfb, 0x88, 0x73, 0xc0, 0xef, 0x80, 0xc9, 0x36, 0x93, - 0xcb, 0xb5, 0x9c, 0xd4, 0xe7, 0x25, 0xeb, 0x24, 0x57, 0x06, 0x89, 0x33, 0x78, 0x07, 0xcc, 0x37, - 0x89, 0x43, 0x6d, 0xb3, 0x42, 0x0c, 0xdb, 0x32, 0x5d, 0x1e, 0x30, 0x93, 0xfa, 0x19, 0x49, 0x3c, - 0x5f, 0x8e, 0x1e, 0xa2, 0x38, 0xad, 0xfa, 0x8f, 0x14, 0x58, 0x0c, 0x15, 0x40, 0xad, 0x3a, 0x71, - 0xe1, 0xef, 0xc1, 0x8a, 0xeb, 0xe1, 0x2a, 0xad, 0xd3, 0xe7, 0xd8, 0xa3, 0xb6, 0xb5, 0x43, 0x2d, - 0xd3, 0x7e, 0x1a, 0x47, 0xcf, 0x77, 0x3b, 0x85, 0x95, 0xca, 0x40, 0x2a, 0x34, 0x04, 0x01, 0xde, - 0x07, 0x73, 0x2e, 0xa9, 0x13, 0xc3, 0x13, 0xf6, 0x4a, 0xbf, 0x5c, 0xee, 0x76, 0x0a, 0x73, 0x95, - 0xc8, 0xfe, 0xfb, 0x4e, 0xe1, 0x54, 0xcc, 0x31, 0xe2, 0x10, 0xc5, 0x98, 0xe1, 0xaf, 0xc1, 0x4c, - 0x93, 0xfd, 0xa2, 0xc4, 0xcd, 0xa5, 0x56, 0xd3, 0x23, 0x22, 0x24, 0xe9, 0x6b, 0x7d, 0x49, 0x7a, - 0x69, 0xa6, 0x2c, 0x41, 0x50, 0x00, 0xa7, 0xbe, 0x4a, 0x81, 0x73, 0xf7, 0x6c, 0x87, 0x3e, 0x67, - 0xc9, 0x5f, 0x2f, 0xdb, 0xe6, 0x9a, 0x04, 0x23, 0x0e, 0x7c, 0x02, 0x66, 0x58, 0x93, 0x31, 0xb1, - 0x87, 0x65, 0x60, 0xfe, 0x30, 0x22, 0x36, 0xe8, 0x15, 0x5a, 0x73, 0xbf, 0xc6, 0x36, 0x5c, 0x8d, - 0x51, 0x6b, 0xed, 0x1b, 0x9a, 0xa8, 0x17, 0x5b, 0xc4, 0xc3, 0x61, 0x4a, 0x87, 0x7b, 0x28, 0x40, - 0x85, 0xbf, 0x02, 0x19, 0xb7, 0x49, 0x0c, 0x19, 0xa0, 0xb7, 0x86, 0x19, 0xd5, 0x5f, 0xc7, 0x4a, - 0x93, 0x18, 0x61, 0x79, 0x61, 0x2b, 0xc4, 0x11, 0xe1, 0x13, 0x30, 0xe5, 0xf2, 0x40, 0xe6, 0x77, - 0x99, 0x2d, 0xdd, 0xfe, 0x00, 0x6c, 0x91, 0x08, 0x41, 0x7e, 0x89, 0x35, 0x92, 0xb8, 0xea, 0x67, - 0x0a, 0x28, 0x0c, 0xe0, 0xd4, 0xc9, 0x1e, 0x6e, 0x53, 0xdb, 0x81, 0x0f, 0xc0, 0x34, 0xdf, 0x79, - 0xd4, 0x94, 0x0e, 0xbc, 0x76, 0xa8, 0x7b, 0xe3, 0x21, 0xaa, 0x67, 0x59, 0xf6, 0x55, 0x04, 0x3b, - 0xf2, 0x71, 0xe0, 0x0e, 0x98, 0xe5, 0x3f, 0xef, 0xda, 0x4f, 0x2d, 0xe9, 0xb7, 0x71, 0x40, 0xe7, - 0x59, 0xd1, 0xaf, 0xf8, 0x00, 0x28, 0xc4, 0x52, 0xff, 0x9c, 0x06, 0xab, 0x03, 0xec, 0x59, 0xb7, - 0x2d, 0x93, 0xb2, 0x18, 0x87, 0xf7, 0x62, 0x69, 0x7e, 0x33, 0x91, 0xe6, 0x97, 0x46, 0xf1, 0x47, - 0xd2, 0x7e, 0x33, 0xb8, 0xa0, 0x54, 0x0c, 0x4b, 0xba, 0xf9, 0x7d, 0xa7, 0xd0, 0x67, 0xb0, 0xd2, - 0x02, 0xa4, 0xf8, 0x65, 0xc0, 0x36, 0x80, 0x75, 0xec, 0x7a, 0x0f, 0x1d, 0x6c, 0xb9, 0x42, 0x12, - 0x6d, 0x10, 0x79, 0xf5, 0xd7, 0x0e, 0x17, 0xb4, 0x8c, 0x43, 0x5f, 0x91, 0x5a, 0xc0, 0xcd, 0x1e, - 0x34, 0xd4, 0x47, 0x02, 0xfc, 0x1e, 0x98, 0x72, 0x08, 0x76, 0x6d, 0x2b, 0x97, 0xe1, 0x56, 0x04, - 0xc1, 0x82, 0xf8, 0x2e, 0x92, 0xa7, 0xf0, 0x2a, 0x98, 0x6e, 0x10, 0xd7, 0xc5, 0x35, 0x92, 0x9b, - 0xe4, 0x84, 0x41, 0x79, 0xdd, 0x12, 0xdb, 0xc8, 0x3f, 0x57, 0x3f, 0x57, 0xc0, 0x85, 0x01, 0x7e, - 0xdc, 0xa4, 0xae, 0x07, 0x7f, 0xdb, 0x93, 0x95, 0xda, 0xe1, 0x0c, 0x64, 0xdc, 0x3c, 0x27, 0x83, - 0x7a, 0xe0, 0xef, 0x44, 0x32, 0x72, 0x07, 0x4c, 0x52, 0x8f, 0x34, 0xfc, 0x3a, 0x53, 0x1a, 0x3f, - 0x6d, 0xc2, 0x0a, 0xbe, 0xc1, 0x80, 0x90, 0xc0, 0x53, 0x5f, 0xa5, 0x07, 0x9a, 0xc5, 0xd2, 0x16, - 0xb6, 0xc1, 0x02, 0x5f, 0xc9, 0x9e, 0x49, 0x76, 0xa5, 0x71, 0xc3, 0x8a, 0xc2, 0x90, 0x19, 0x45, - 0x3f, 0x2b, 0xb5, 0x58, 0xa8, 0xc4, 0x50, 0x51, 0x42, 0x0a, 0xbc, 0x01, 0xb2, 0x0d, 0x6a, 0x21, - 0xd2, 0xac, 0x53, 0x03, 0xbb, 0xb2, 0x09, 0x2d, 0x76, 0x3b, 0x85, 0xec, 0x56, 0xb8, 0x8d, 0xa2, - 0x34, 0xf0, 0xc7, 0x20, 0xdb, 0xc0, 0xcf, 0x02, 0x16, 0xd1, 0x2c, 0x4e, 0x49, 0x79, 0xd9, 0xad, - 0xf0, 0x08, 0x45, 0xe9, 0x60, 0x99, 0xc5, 0x00, 0x6b, 0xb3, 0x6e, 0x2e, 0xc3, 0x9d, 0xfb, 0xdd, - 0x91, 0x0d, 0x99, 0x97, 0xb7, 0x48, 0xa8, 0x70, 0x6e, 0xe4, 0xc3, 0x40, 0x13, 0xcc, 0x54, 0x65, - 0xa9, 0xe1, 0x61, 0x95, 0x2d, 0xfd, 0xe4, 0x03, 0xee, 0x4b, 0x22, 0xe8, 0x73, 0x2c, 0x24, 0xfc, - 0x15, 0x0a, 0x90, 0xd5, 0x97, 0x19, 0x70, 0x71, 0x68, 0x89, 0x84, 0x3f, 0x07, 0xd0, 0xae, 0xba, - 0xc4, 0x69, 0x13, 0xf3, 0x17, 0xe2, 0x91, 0xc0, 0x66, 0x3a, 0x76, 0x7f, 0x69, 0xfd, 0x2c, 0xcb, - 0xa6, 0xed, 0x9e, 0x53, 0xd4, 0x87, 0x03, 0x1a, 0x60, 0x9e, 0xe5, 0x98, 0xb8, 0x31, 0x2a, 0xc7, - 0xc7, 0xf1, 0x12, 0x78, 0x99, 0x4d, 0x03, 0x9b, 0x51, 0x10, 0x14, 0xc7, 0x84, 0x6b, 0x60, 0x51, - 0x4e, 0x32, 0x89, 0x1b, 0x3c, 0x27, 0xfd, 0xbc, 0xb8, 0x1e, 0x3f, 0x46, 0x49, 0x7a, 0x06, 0x61, - 0x12, 0x97, 0x3a, 0xc4, 0x0c, 0x20, 0x32, 0x71, 0x88, 0xbb, 0xf1, 0x63, 0x94, 0xa4, 0x87, 0x35, - 0xb0, 0x20, 0x51, 0xe5, 0xad, 0xe6, 0x26, 0x79, 0x4c, 0x8c, 0x1e, 0x32, 0x65, 0x5b, 0x0a, 0xe2, - 0x7b, 0x3d, 0x06, 0x83, 0x12, 0xb0, 0xd0, 0x06, 0xc0, 0xf0, 0x8b, 0xa6, 0x9b, 0x9b, 0xe2, 0x42, - 0xee, 0x8c, 0x1f, 0x25, 0x41, 0xe1, 0x0d, 0x3b, 0x7a, 0xb0, 0xe5, 0xa2, 0x88, 0x08, 0xf5, 0x6f, - 0x0a, 0x58, 0x4a, 0x0e, 0xa9, 0xc1, 0x7b, 0x40, 0x19, 0xf8, 0x1e, 0xf8, 0x1d, 0x98, 0x11, 0x33, - 0x8f, 0xed, 0xc8, 0x6b, 0xff, 0xd1, 0x21, 0xcb, 0x1a, 0xae, 0x92, 0x7a, 0x45, 0xb2, 0x8a, 0x20, - 0xf6, 0x57, 0x28, 0x80, 0x54, 0x5f, 0x64, 0x00, 0x08, 0x73, 0x0a, 0xde, 0x8c, 0xf5, 0xb1, 0xd5, - 0x44, 0x1f, 0x5b, 0x8a, 0x3e, 0x2e, 0x22, 0x3d, 0xeb, 0x01, 0x98, 0xb2, 0x79, 0x99, 0x91, 0x1a, - 0x5e, 0x1f, 0xe2, 0xc7, 0x60, 0xde, 0x09, 0x80, 0x74, 0xc0, 0x1a, 0x83, 0xac, 0x53, 0x12, 0x08, - 0x6e, 0x80, 0x4c, 0xd3, 0x36, 0xfd, 0x29, 0x65, 0xd8, 0x58, 0x57, 0xb6, 0x4d, 0x37, 0x06, 0x37, - 0xc3, 0x34, 0x66, 0xbb, 0x88, 0x43, 0xb0, 0x29, 0xd1, 0xff, 0x94, 0xc0, 0xc3, 0x31, 0x5b, 0x2a, - 0x0e, 0x81, 0xeb, 0xf7, 0x60, 0x17, 0xde, 0xf3, 0x4f, 0x50, 0x00, 0x07, 0xff, 0x08, 0x96, 0x8d, - 0xe4, 0x03, 0x38, 0x37, 0x3d, 0x72, 0xb0, 0x1a, 0xfa, 0x75, 0x40, 0x3f, 0xd3, 0xed, 0x14, 0x96, - 0x7b, 0x48, 0x50, 0xaf, 0x24, 0x66, 0x19, 0x91, 0xef, 0x26, 0x59, 0xe7, 0x86, 0x59, 0xd6, 0xef, - 0x85, 0x28, 0x2c, 0xf3, 0x4f, 0x50, 0x00, 0xa7, 0xfe, 0x3d, 0x03, 0xe6, 0x62, 0x6f, 0xb1, 0x63, - 0x8e, 0x0c, 0x91, 0xcc, 0x47, 0x16, 0x19, 0x02, 0xee, 0x48, 0x23, 0x43, 0x40, 0x1e, 0x53, 0x64, - 0x08, 0x61, 0xc7, 0x14, 0x19, 0x11, 0xcb, 0xfa, 0x44, 0xc6, 0x27, 0x29, 0x3f, 0x32, 0xc4, 0xb0, - 0x70, 0xb8, 0xc8, 0x10, 0xb4, 0x91, 0xc8, 0xd8, 0x8e, 0x3e, 0x6f, 0x47, 0xcc, 0x6a, 0x9a, 0xef, - 0x56, 0xed, 0x41, 0x0b, 0x5b, 0x1e, 0xf5, 0x0e, 0xf4, 0xd9, 0x9e, 0xa7, 0xb0, 0x09, 0xe6, 0x70, - 0x9b, 0x38, 0xb8, 0x46, 0xf8, 0xb6, 0x8c, 0x8f, 0x71, 0x71, 0x97, 0xd8, 0x4b, 0x74, 0x2d, 0x82, - 0x83, 0x62, 0xa8, 0xac, 0xa5, 0xcb, 0xf5, 0x23, 0x2f, 0x78, 0xe2, 0xca, 0x2e, 0xc7, 0x5b, 0xfa, - 0x5a, 0xcf, 0x29, 0xea, 0xc3, 0xa1, 0xfe, 0x35, 0x05, 0x96, 0x7b, 0x3e, 0x2e, 0x84, 0x4e, 0x51, - 0x3e, 0x92, 0x53, 0x52, 0xc7, 0xe8, 0x94, 0xf4, 0xd8, 0x4e, 0xf9, 0x77, 0x0a, 0xc0, 0xde, 0xfe, - 0x00, 0x0f, 0xf8, 0x58, 0x61, 0x38, 0xb4, 0x4a, 0x4c, 0x71, 0xfc, 0x2d, 0x67, 0xe0, 0xe8, 0x38, - 0x12, 0x85, 0x45, 0x49, 0x39, 0x47, 0xff, 0x91, 0x35, 0xfc, 0xa4, 0x95, 0x3e, 0xb2, 0x4f, 0x5a, - 0xea, 0xff, 0x92, 0x7e, 0x3b, 0x81, 0x9f, 0xcf, 0xfa, 0xdd, 0x72, 0xfa, 0x78, 0x6e, 0x59, 0xfd, - 0x8f, 0x02, 0x96, 0x92, 0x63, 0xc4, 0x09, 0xf9, 0x76, 0xfa, 0xff, 0xb8, 0xea, 0x27, 0xf1, 0xbb, - 0xe9, 0x4b, 0x05, 0x9c, 0x3e, 0x39, 0x7f, 0x93, 0xa8, 0xff, 0xea, 0x55, 0xf7, 0x04, 0xfc, 0xd9, - 0xa1, 0xff, 0xf4, 0xf5, 0xbb, 0xfc, 0xc4, 0x9b, 0x77, 0xf9, 0x89, 0xb7, 0xef, 0xf2, 0x13, 0x7f, - 0xea, 0xe6, 0x95, 0xd7, 0xdd, 0xbc, 0xf2, 0xa6, 0x9b, 0x57, 0xde, 0x76, 0xf3, 0xca, 0x17, 0xdd, - 0xbc, 0xf2, 0x97, 0x2f, 0xf3, 0x13, 0xbf, 0x39, 0x3f, 0xf0, 0x9f, 0xc2, 0x6f, 0x02, 0x00, 0x00, - 0xff, 0xff, 0xca, 0x8b, 0x47, 0xba, 0x45, 0x1c, 0x00, 0x00, + // 1742 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x59, 0xc9, 0x8f, 0x1b, 0x4b, + 0x19, 0x9f, 0xb6, 0x3d, 0x5b, 0x79, 0xd6, 0xca, 0xe6, 0x4c, 0x14, 0x7b, 0xd4, 0x04, 0xb2, 0x40, + 0xda, 0xc4, 0x84, 0x28, 0x22, 0x07, 0x34, 0x3d, 0x01, 0x32, 0xca, 0x0c, 0xe3, 0x94, 0x27, 0x19, + 0x76, 0xa5, 0xdc, 0x5d, 0xe3, 0x29, 0xc6, 0xee, 0xb6, 0xba, 0xdb, 0x4e, 0x26, 0x12, 0x12, 0x17, + 0xee, 0x08, 0x14, 0xf1, 0x4f, 0x44, 0x9c, 0x40, 0xe1, 0x00, 0x12, 0x12, 0x1c, 0x72, 0x41, 0xca, + 0x81, 0x43, 0x4e, 0x16, 0x31, 0xd2, 0x3b, 0xbe, 0xe3, 0x3b, 0xe4, 0xf4, 0x54, 0x4b, 0xaf, 0xde, + 0xc6, 0x79, 0x93, 0x91, 0xe6, 0xe6, 0xaa, 0xfa, 0xbe, 0xdf, 0xb7, 0xd4, 0xb7, 0x55, 0x1b, 0x5c, + 0x3f, 0xb8, 0xeb, 0x6a, 0xd4, 0x2e, 0xe2, 0x26, 0x2d, 0xe2, 0x96, 0x67, 0xbb, 0x06, 0xae, 0x53, + 0xab, 0x56, 0x6c, 0x97, 0x8a, 0x35, 0x62, 0x11, 0x07, 0x7b, 0xc4, 0xd4, 0x9a, 0x8e, 0xed, 0xd9, + 0xf0, 0xa2, 0x20, 0xd5, 0x70, 0x93, 0x6a, 0x11, 0x52, 0xad, 0x5d, 0x5a, 0xb9, 0x59, 0xa3, 0xde, + 0x7e, 0xab, 0xaa, 0x19, 0x76, 0xa3, 0x58, 0xb3, 0x6b, 0x76, 0x91, 0x73, 0x54, 0x5b, 0x7b, 0x7c, + 0xc5, 0x17, 0xfc, 0x97, 0x40, 0x5a, 0x51, 0x23, 0x42, 0x0d, 0xdb, 0x21, 0xc5, 0xf6, 0xad, 0xa4, + 0xb4, 0x95, 0xdb, 0x21, 0x4d, 0x03, 0x1b, 0xfb, 0xd4, 0x22, 0xce, 0x61, 0xb1, 0x79, 0x50, 0xe3, + 0x4c, 0x0e, 0x71, 0xed, 0x96, 0x63, 0x90, 0xb1, 0xb8, 0xdc, 0x62, 0x83, 0x78, 0xb8, 0x9f, 0xac, + 0xe2, 0x20, 0x2e, 0xa7, 0x65, 0x79, 0xb4, 0xd1, 0x2b, 0xe6, 0xce, 0x28, 0x06, 0xd7, 0xd8, 0x27, + 0x0d, 0x9c, 0xe4, 0x53, 0x3f, 0x53, 0xc0, 0xe5, 0x75, 0xdb, 0xf2, 0x30, 0xe3, 0x40, 0xd2, 0x88, + 0x2d, 0xe2, 0x39, 0xd4, 0xa8, 0xf0, 0xdf, 0x70, 0x1d, 0x64, 0x2c, 0xdc, 0x20, 0x39, 0x65, 0x55, + 0xb9, 0x36, 0xab, 0x17, 0xdf, 0x74, 0x0a, 0x13, 0xdd, 0x4e, 0x21, 0xf3, 0x63, 0xdc, 0x20, 0x1f, + 0x3a, 0x85, 0x42, 0xaf, 0xe3, 0x34, 0x1f, 0x86, 0x91, 0x20, 0xce, 0x0c, 0xb7, 0xc1, 0x94, 0x87, + 0x9d, 0x1a, 0xf1, 0x72, 0xa9, 0x55, 0xe5, 0x5a, 0xb6, 0x74, 0x55, 0x1b, 0x78, 0x75, 0x9a, 0x90, + 0xbe, 0xc3, 0xc9, 0xf5, 0x05, 0x29, 0x6f, 0x4a, 0xac, 0x91, 0x84, 0x81, 0x45, 0x30, 0x6b, 0xf8, + 0x6a, 0xe7, 0xd2, 0x5c, 0xb5, 0x65, 0x49, 0x3a, 0x1b, 0xda, 0x13, 0xd2, 0xa8, 0x9f, 0x0f, 0x31, + 0xd4, 0xc3, 0x5e, 0xcb, 0x3d, 0x1e, 0x43, 0x77, 0xc1, 0xb4, 0xd1, 0x72, 0x1c, 0x62, 0xf9, 0x96, + 0x7e, 0x6b, 0xa4, 0xa5, 0x4f, 0x70, 0xbd, 0x45, 0x84, 0x0e, 0xfa, 0xa2, 0x94, 0x3a, 0xbd, 0x2e, + 0x40, 0x90, 0x8f, 0x36, 0xbe, 0xc1, 0x2f, 0x15, 0x70, 0x69, 0xdd, 0xb1, 0x5d, 0xf7, 0x09, 0x71, + 0x5c, 0x6a, 0x5b, 0xdb, 0xd5, 0x5f, 0x13, 0xc3, 0x43, 0x64, 0x8f, 0x38, 0xc4, 0x32, 0x08, 0x5c, + 0x05, 0x99, 0x03, 0x6a, 0x99, 0xd2, 0xdc, 0x39, 0xdf, 0xdc, 0x87, 0xd4, 0x32, 0x11, 0x3f, 0x61, + 0x14, 0xdc, 0x21, 0xa9, 0x38, 0x45, 0xc4, 0xda, 0x12, 0x00, 0xb8, 0x49, 0xa5, 0x00, 0xa9, 0x15, + 0x94, 0x74, 0x60, 0xad, 0xbc, 0x21, 0x4f, 0x50, 0x84, 0x4a, 0xfd, 0xbb, 0x02, 0xce, 0xfe, 0xe0, + 0xb9, 0x47, 0x1c, 0x0b, 0xd7, 0x63, 0x81, 0x56, 0x01, 0x53, 0x0d, 0xbe, 0xe6, 0x2a, 0x65, 0x4b, + 0xdf, 0x1c, 0xe9, 0xb9, 0x0d, 0x93, 0x58, 0x1e, 0xdd, 0xa3, 0xc4, 0x09, 0xe3, 0x44, 0x9c, 0x20, + 0x09, 0x75, 0xec, 0x81, 0xa7, 0xfe, 0xbb, 0x57, 0x7d, 0x11, 0x3e, 0x9f, 0x44, 0xfd, 0x4f, 0x15, + 0x4e, 0xea, 0x9f, 0x15, 0xb0, 0xf4, 0xa0, 0xbc, 0x56, 0x11, 0xdc, 0x65, 0xbb, 0x4e, 0x8d, 0x43, + 0x78, 0x17, 0x64, 0xbc, 0xc3, 0xa6, 0x9f, 0x01, 0x57, 0xfc, 0x0b, 0xdf, 0x39, 0x6c, 0xb2, 0x0c, + 0x38, 0x9b, 0xa4, 0x67, 0xfb, 0x88, 0x73, 0xc0, 0xaf, 0x81, 0xc9, 0x36, 0x93, 0xcb, 0xb5, 0x9c, + 0xd4, 0xe7, 0x25, 0xeb, 0x24, 0x57, 0x06, 0x89, 0x33, 0x78, 0x0f, 0xcc, 0x37, 0x89, 0x43, 0x6d, + 0xb3, 0x42, 0x0c, 0xdb, 0x32, 0x5d, 0x1e, 0x30, 0x93, 0xfa, 0x39, 0x49, 0x3c, 0x5f, 0x8e, 0x1e, + 0xa2, 0x38, 0xad, 0xfa, 0x45, 0x0a, 0x2c, 0x86, 0x0a, 0xa0, 0x56, 0x9d, 0xb8, 0xf0, 0x57, 0x60, + 0xc5, 0xf5, 0x70, 0x95, 0xd6, 0xe9, 0x0b, 0xec, 0x51, 0xdb, 0xda, 0xa5, 0x96, 0x69, 0x3f, 0x8b, + 0xa3, 0xe7, 0xbb, 0x9d, 0xc2, 0x4a, 0x65, 0x20, 0x15, 0x1a, 0x82, 0x00, 0x1f, 0x82, 0x39, 0x97, + 0xd4, 0x89, 0xe1, 0x09, 0x7b, 0xa5, 0x5f, 0xae, 0x76, 0x3b, 0x85, 0xb9, 0x4a, 0x64, 0xff, 0x43, + 0xa7, 0x70, 0x26, 0xe6, 0x18, 0x71, 0x88, 0x62, 0xcc, 0xf0, 0xa7, 0x60, 0xa6, 0xc9, 0x7e, 0x51, + 0xe2, 0xe6, 0x52, 0xab, 0xe9, 0x11, 0x11, 0x92, 0xf4, 0xb5, 0xbe, 0x24, 0xbd, 0x34, 0x53, 0x96, + 0x20, 0x28, 0x80, 0x83, 0x3f, 0x07, 0xb3, 0x9e, 0x5d, 0x27, 0x0e, 0xb6, 0x0c, 0x92, 0xcb, 0xf0, + 0x38, 0xd1, 0x22, 0xd8, 0x41, 0x43, 0xd0, 0x9a, 0x07, 0x35, 0x2e, 0xcc, 0xef, 0x56, 0xda, 0xa3, + 0x16, 0xb6, 0x3c, 0xea, 0x1d, 0xea, 0xf3, 0xac, 0x8e, 0xec, 0xf8, 0x20, 0x28, 0xc4, 0x53, 0x5f, + 0xa7, 0xc0, 0x85, 0x07, 0xb6, 0x43, 0x5f, 0xb0, 0xca, 0x52, 0x2f, 0xdb, 0xe6, 0x9a, 0xd4, 0x94, + 0x38, 0xf0, 0x29, 0x98, 0x61, 0x1d, 0xcc, 0xc4, 0x1e, 0x96, 0x51, 0xff, 0xed, 0x61, 0x72, 0x5d, + 0x8d, 0x51, 0x6b, 0xed, 0x5b, 0x9a, 0x28, 0x46, 0x5b, 0xc4, 0xc3, 0x61, 0xbd, 0x08, 0xf7, 0x50, + 0x80, 0x0a, 0x7f, 0x02, 0x32, 0x6e, 0x93, 0x18, 0x32, 0xfa, 0xef, 0x0c, 0xf3, 0x58, 0x7f, 0x1d, + 0x2b, 0x4d, 0x62, 0x84, 0xb5, 0x8b, 0xad, 0x10, 0x47, 0x84, 0x4f, 0xc1, 0x94, 0xcb, 0xb3, 0x84, + 0x07, 0x4a, 0xb6, 0x74, 0xf7, 0x23, 0xb0, 0x45, 0x96, 0x05, 0xc9, 0x2b, 0xd6, 0x48, 0xe2, 0xaa, + 0xff, 0x51, 0x40, 0x61, 0x00, 0xa7, 0x4e, 0xf6, 0x71, 0x9b, 0xda, 0x0e, 0x7c, 0x04, 0xa6, 0xf9, + 0xce, 0xe3, 0xa6, 0x74, 0xe0, 0x8d, 0x23, 0x05, 0x05, 0x8f, 0x7f, 0x3d, 0xcb, 0x52, 0xbb, 0x22, + 0xd8, 0x91, 0x8f, 0x03, 0x77, 0xc1, 0x2c, 0xff, 0x79, 0xdf, 0x7e, 0x66, 0x49, 0xbf, 0x8d, 0x03, + 0xca, 0x23, 0xa1, 0xe2, 0x03, 0xa0, 0x10, 0x4b, 0xfd, 0x5d, 0x1a, 0xac, 0x0e, 0xb0, 0x67, 0xdd, + 0xb6, 0x4c, 0xca, 0x12, 0x08, 0x3e, 0x88, 0xd5, 0x90, 0xdb, 0x89, 0x1a, 0x72, 0x65, 0x14, 0x7f, + 0xa4, 0xa6, 0x6c, 0x06, 0x17, 0x94, 0x8a, 0x61, 0x49, 0x37, 0x7f, 0xe8, 0x14, 0xfa, 0x4c, 0x6d, + 0x5a, 0x80, 0x14, 0xbf, 0x0c, 0xd8, 0x06, 0xb0, 0x8e, 0x5d, 0x6f, 0xc7, 0xc1, 0x96, 0x2b, 0x24, + 0xd1, 0x06, 0x91, 0x57, 0x7f, 0xe3, 0x68, 0x41, 0xcb, 0x38, 0xf4, 0x15, 0xa9, 0x05, 0xdc, 0xec, + 0x41, 0x43, 0x7d, 0x24, 0xc0, 0x6f, 0x80, 0x29, 0x87, 0x60, 0xd7, 0xb6, 0x78, 0x62, 0xce, 0x86, + 0xc1, 0x82, 0xf8, 0x2e, 0x92, 0xa7, 0xf0, 0x3a, 0x98, 0x6e, 0x10, 0xd7, 0xc5, 0x35, 0x92, 0x9b, + 0xe4, 0x84, 0x41, 0xed, 0xde, 0x12, 0xdb, 0xc8, 0x3f, 0x57, 0xff, 0xab, 0x80, 0x4b, 0x03, 0xfc, + 0xb8, 0x49, 0x5d, 0x0f, 0xfe, 0xa2, 0x27, 0x2b, 0xb5, 0xa3, 0x19, 0xc8, 0xb8, 0x79, 0x4e, 0x06, + 0xc5, 0xc6, 0xdf, 0x89, 0x64, 0xe4, 0x2e, 0x98, 0xa4, 0x1e, 0x69, 0xf8, 0x45, 0xac, 0x34, 0x7e, + 0xda, 0x84, 0xed, 0x61, 0x83, 0x01, 0x21, 0x81, 0xa7, 0xbe, 0x4e, 0x0f, 0x34, 0x8b, 0xa5, 0x2d, + 0x6c, 0x83, 0x05, 0xbe, 0x92, 0x0d, 0x99, 0xec, 0x49, 0xe3, 0x86, 0x15, 0x85, 0x21, 0x03, 0x90, + 0x7e, 0x5e, 0x6a, 0xb1, 0x50, 0x89, 0xa1, 0xa2, 0x84, 0x14, 0x78, 0x0b, 0x64, 0x1b, 0xd4, 0x42, + 0xa4, 0x59, 0xa7, 0x06, 0x76, 0x65, 0x87, 0x5b, 0xec, 0x76, 0x0a, 0xd9, 0xad, 0x70, 0x1b, 0x45, + 0x69, 0xe0, 0x77, 0x41, 0xb6, 0x81, 0x9f, 0x07, 0x2c, 0xa2, 0x13, 0x9d, 0x91, 0xf2, 0xb2, 0x5b, + 0xe1, 0x11, 0x8a, 0xd2, 0xc1, 0x32, 0x8b, 0x01, 0xd6, 0xc3, 0xdd, 0x5c, 0x86, 0x3b, 0xf7, 0xeb, + 0x23, 0xbb, 0x3d, 0x2f, 0x6f, 0x91, 0x50, 0xe1, 0xdc, 0xc8, 0x87, 0x81, 0x26, 0x98, 0xa9, 0xca, + 0x52, 0xc3, 0xc3, 0x2a, 0x5b, 0xfa, 0xde, 0x47, 0xdc, 0x97, 0x44, 0xd0, 0xe7, 0x58, 0x48, 0xf8, + 0x2b, 0x14, 0x20, 0xab, 0xaf, 0x32, 0xe0, 0xf2, 0xd0, 0x12, 0x09, 0x7f, 0x08, 0xa0, 0x5d, 0x75, + 0x89, 0xd3, 0x26, 0xe6, 0x8f, 0xc4, 0x0b, 0x84, 0x0d, 0x8c, 0xec, 0xfe, 0xd2, 0xfa, 0x79, 0x96, + 0x4d, 0xdb, 0x3d, 0xa7, 0xa8, 0x0f, 0x07, 0x34, 0xc0, 0x3c, 0xcb, 0x31, 0x71, 0x63, 0x54, 0xce, + 0xa6, 0xe3, 0x25, 0xf0, 0x32, 0x1b, 0x35, 0x36, 0xa3, 0x20, 0x28, 0x8e, 0x09, 0xd7, 0xc0, 0xa2, + 0x1c, 0x93, 0x12, 0x37, 0x78, 0x41, 0xfa, 0x79, 0x71, 0x3d, 0x7e, 0x8c, 0x92, 0xf4, 0x0c, 0xc2, + 0x24, 0x2e, 0x75, 0x88, 0x19, 0x40, 0x64, 0xe2, 0x10, 0xf7, 0xe3, 0xc7, 0x28, 0x49, 0x0f, 0x6b, + 0x60, 0x41, 0xa2, 0xca, 0x5b, 0xcd, 0x4d, 0xf2, 0x98, 0x18, 0x3d, 0xc1, 0xca, 0xb6, 0x14, 0xc4, + 0xf7, 0x7a, 0x0c, 0x06, 0x25, 0x60, 0xa1, 0x0d, 0x80, 0xe1, 0x17, 0x4d, 0x37, 0x37, 0xc5, 0x85, + 0xdc, 0x1b, 0x3f, 0x4a, 0x82, 0xc2, 0x1b, 0x76, 0xf4, 0x60, 0xcb, 0x45, 0x11, 0x11, 0xea, 0x1f, + 0x15, 0xb0, 0x94, 0x9c, 0x80, 0x83, 0xc7, 0x86, 0x32, 0xf0, 0xb1, 0xf1, 0x4b, 0x30, 0x23, 0x06, + 0x2a, 0xdb, 0x91, 0xd7, 0xfe, 0x9d, 0x23, 0x96, 0x35, 0x5c, 0x25, 0xf5, 0x8a, 0x64, 0x15, 0x41, + 0xec, 0xaf, 0x50, 0x00, 0xa9, 0xbe, 0xcc, 0x00, 0x10, 0xe6, 0x14, 0xbc, 0x1d, 0xeb, 0x63, 0xab, + 0x89, 0x3e, 0xb6, 0x14, 0x7d, 0xb9, 0x44, 0x7a, 0xd6, 0x23, 0x30, 0x65, 0xf3, 0x32, 0x23, 0x35, + 0xbc, 0x39, 0xc4, 0x8f, 0xc1, 0xbc, 0x13, 0x00, 0xe9, 0x80, 0x35, 0x06, 0x59, 0xa7, 0x24, 0x10, + 0xdc, 0x00, 0x99, 0xa6, 0x6d, 0xfa, 0x53, 0xca, 0xb0, 0x99, 0xb1, 0x6c, 0x9b, 0x6e, 0x0c, 0x6e, + 0x86, 0x69, 0xcc, 0x76, 0x11, 0x87, 0x60, 0x23, 0xa8, 0x3f, 0xf9, 0xc9, 0x31, 0xb1, 0x38, 0x04, + 0xae, 0xdf, 0xd7, 0x00, 0xe1, 0x3d, 0xff, 0x04, 0x05, 0x70, 0xf0, 0x37, 0x60, 0xd9, 0x48, 0xbe, + 0xae, 0x73, 0xd3, 0x23, 0x07, 0xab, 0xa1, 0x9f, 0x1e, 0xf4, 0x73, 0xdd, 0x4e, 0x61, 0xb9, 0x87, + 0x04, 0xf5, 0x4a, 0x62, 0x96, 0x11, 0xf9, 0x28, 0x93, 0x75, 0x6e, 0x98, 0x65, 0xfd, 0x9e, 0x9f, + 0xc2, 0x32, 0xff, 0x04, 0x05, 0x70, 0xea, 0x9f, 0x32, 0x60, 0x2e, 0xf6, 0xd0, 0x3b, 0xe1, 0xc8, + 0x10, 0xc9, 0x7c, 0x6c, 0x91, 0x21, 0xe0, 0x8e, 0x35, 0x32, 0x04, 0xe4, 0x09, 0x45, 0x86, 0x10, + 0x76, 0x42, 0x91, 0x11, 0xb1, 0xac, 0x4f, 0x64, 0xfc, 0x2b, 0xe5, 0x47, 0x86, 0x18, 0x16, 0x8e, + 0x16, 0x19, 0x82, 0x36, 0x12, 0x19, 0xdb, 0xd1, 0xb7, 0xf3, 0xf8, 0x2f, 0xb7, 0xd9, 0x9e, 0x77, + 0xb6, 0x09, 0xe6, 0x70, 0x9b, 0x38, 0xb8, 0x46, 0xf8, 0xb6, 0x8c, 0x8f, 0x71, 0x71, 0x97, 0xd8, + 0x33, 0x77, 0x2d, 0x82, 0x83, 0x62, 0xa8, 0xac, 0xa5, 0xcb, 0xf5, 0x63, 0x2f, 0x78, 0x3f, 0xcb, + 0x2e, 0xc7, 0x5b, 0xfa, 0x5a, 0xcf, 0x29, 0xea, 0xc3, 0xa1, 0xfe, 0x21, 0x05, 0x96, 0x7b, 0xbe, + 0x5c, 0x84, 0x4e, 0x51, 0x3e, 0x91, 0x53, 0x52, 0x27, 0xe8, 0x94, 0xf4, 0xd8, 0x4e, 0xf9, 0x6b, + 0x0a, 0xc0, 0xde, 0xfe, 0x00, 0x0f, 0xf9, 0x58, 0x61, 0x38, 0xb4, 0x4a, 0x4c, 0x71, 0xfc, 0x15, + 0x67, 0xe0, 0xe8, 0x38, 0x12, 0x85, 0x45, 0x49, 0x39, 0xc7, 0xff, 0x05, 0x37, 0xfc, 0x5e, 0x96, + 0x3e, 0xb6, 0xef, 0x65, 0xea, 0x3f, 0x92, 0x7e, 0x3b, 0x85, 0xdf, 0xe6, 0xfa, 0xdd, 0x72, 0xfa, + 0x64, 0x6e, 0x59, 0xfd, 0x9b, 0x02, 0x96, 0x92, 0x63, 0xc4, 0x29, 0xf9, 0x30, 0xfb, 0xcf, 0xb8, + 0xea, 0xa7, 0xf1, 0xa3, 0xec, 0x2b, 0x05, 0x9c, 0x3d, 0x3d, 0xff, 0xc1, 0xa8, 0x7f, 0xe9, 0x55, + 0xf7, 0x14, 0xfc, 0x93, 0xa2, 0x7f, 0xff, 0xcd, 0xfb, 0xfc, 0xc4, 0xdb, 0xf7, 0xf9, 0x89, 0x77, + 0xef, 0xf3, 0x13, 0xbf, 0xed, 0xe6, 0x95, 0x37, 0xdd, 0xbc, 0xf2, 0xb6, 0x9b, 0x57, 0xde, 0x75, + 0xf3, 0xca, 0xff, 0xba, 0x79, 0xe5, 0xf7, 0xff, 0xcf, 0x4f, 0xfc, 0xec, 0xe2, 0xc0, 0xbf, 0x21, + 0xbf, 0x0c, 0x00, 0x00, 0xff, 0xff, 0xbe, 0x23, 0xae, 0x54, 0xa2, 0x1c, 0x00, 0x00, } func (m *ContainerResourceMetricSource) Marshal() (dAtA []byte, err error) { @@ -1126,6 +1127,18 @@ func (m *HPAScalingRules) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.Tolerance != nil { + { + size, err := m.Tolerance.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } if m.StabilizationWindowSeconds != nil { i = encodeVarintGenerated(dAtA, i, uint64(*m.StabilizationWindowSeconds)) i-- @@ -2203,6 +2216,10 @@ func (m *HPAScalingRules) Size() (n int) { if m.StabilizationWindowSeconds != nil { n += 1 + sovGenerated(uint64(*m.StabilizationWindowSeconds)) } + if m.Tolerance != nil { + l = m.Tolerance.Size() + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -2619,6 +2636,7 @@ func (this *HPAScalingRules) String() string { `SelectPolicy:` + valueToStringGenerated(this.SelectPolicy) + `,`, `Policies:` + repeatedStringForPolicies + `,`, `StabilizationWindowSeconds:` + valueToStringGenerated(this.StabilizationWindowSeconds) + `,`, + `Tolerance:` + strings.Replace(fmt.Sprintf("%v", this.Tolerance), "Quantity", "resource.Quantity", 1) + `,`, `}`, }, "") return s @@ -3770,6 +3788,42 @@ func (m *HPAScalingRules) Unmarshal(dAtA []byte) error { } } m.StabilizationWindowSeconds = &v + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Tolerance", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Tolerance == nil { + m.Tolerance = &resource.Quantity{} + } + if err := m.Tolerance.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/go-controller/vendor/k8s.io/api/autoscaling/v2/generated.proto b/go-controller/vendor/k8s.io/api/autoscaling/v2/generated.proto index 4e6dc0592a..04c34d6e16 100644 --- a/go-controller/vendor/k8s.io/api/autoscaling/v2/generated.proto +++ b/go-controller/vendor/k8s.io/api/autoscaling/v2/generated.proto @@ -112,12 +112,18 @@ message HPAScalingPolicy { optional int32 periodSeconds = 3; } -// HPAScalingRules configures the scaling behavior for one direction. -// These Rules are applied after calculating DesiredReplicas from metrics for the HPA. +// HPAScalingRules configures the scaling behavior for one direction via +// scaling Policy Rules and a configurable metric tolerance. +// +// Scaling Policy Rules are applied after calculating DesiredReplicas from metrics for the HPA. // They can limit the scaling velocity by specifying scaling policies. // They can prevent flapping by specifying the stabilization window, so that the // number of replicas is not set instantly, instead, the safest value from the stabilization // window is chosen. +// +// The tolerance is applied to the metric values and prevents scaling too +// eagerly for small metric variations. (Note that setting a tolerance requires +// enabling the alpha HPAConfigurableTolerance feature gate.) message HPAScalingRules { // stabilizationWindowSeconds is the number of seconds for which past recommendations should be // considered while scaling up or scaling down. @@ -134,10 +140,28 @@ message HPAScalingRules { optional string selectPolicy = 1; // policies is a list of potential scaling polices which can be used during scaling. - // At least one policy must be specified, otherwise the HPAScalingRules will be discarded as invalid + // If not set, use the default values: + // - For scale up: allow doubling the number of pods, or an absolute change of 4 pods in a 15s window. + // - For scale down: allow all pods to be removed in a 15s window. // +listType=atomic // +optional repeated HPAScalingPolicy policies = 2; + + // tolerance is the tolerance on the ratio between the current and desired + // metric value under which no updates are made to the desired number of + // replicas (e.g. 0.01 for 1%). Must be greater than or equal to zero. If not + // set, the default cluster-wide tolerance is applied (by default 10%). + // + // For example, if autoscaling is configured with a memory consumption target of 100Mi, + // and scale-down and scale-up tolerances of 5% and 1% respectively, scaling will be + // triggered when the actual consumption falls below 95Mi or exceeds 101Mi. + // + // This is an alpha field and requires enabling the HPAConfigurableTolerance + // feature gate. + // + // +featureGate=HPAConfigurableTolerance + // +optional + optional .k8s.io.apimachinery.pkg.api.resource.Quantity tolerance = 4; } // HorizontalPodAutoscaler is the configuration for a horizontal pod diff --git a/go-controller/vendor/k8s.io/api/autoscaling/v2/types.go b/go-controller/vendor/k8s.io/api/autoscaling/v2/types.go index 99e8db09dc..9ce69b1edc 100644 --- a/go-controller/vendor/k8s.io/api/autoscaling/v2/types.go +++ b/go-controller/vendor/k8s.io/api/autoscaling/v2/types.go @@ -171,12 +171,18 @@ const ( DisabledPolicySelect ScalingPolicySelect = "Disabled" ) -// HPAScalingRules configures the scaling behavior for one direction. -// These Rules are applied after calculating DesiredReplicas from metrics for the HPA. +// HPAScalingRules configures the scaling behavior for one direction via +// scaling Policy Rules and a configurable metric tolerance. +// +// Scaling Policy Rules are applied after calculating DesiredReplicas from metrics for the HPA. // They can limit the scaling velocity by specifying scaling policies. // They can prevent flapping by specifying the stabilization window, so that the // number of replicas is not set instantly, instead, the safest value from the stabilization // window is chosen. +// +// The tolerance is applied to the metric values and prevents scaling too +// eagerly for small metric variations. (Note that setting a tolerance requires +// enabling the alpha HPAConfigurableTolerance feature gate.) type HPAScalingRules struct { // stabilizationWindowSeconds is the number of seconds for which past recommendations should be // considered while scaling up or scaling down. @@ -193,10 +199,28 @@ type HPAScalingRules struct { SelectPolicy *ScalingPolicySelect `json:"selectPolicy,omitempty" protobuf:"bytes,1,opt,name=selectPolicy"` // policies is a list of potential scaling polices which can be used during scaling. - // At least one policy must be specified, otherwise the HPAScalingRules will be discarded as invalid + // If not set, use the default values: + // - For scale up: allow doubling the number of pods, or an absolute change of 4 pods in a 15s window. + // - For scale down: allow all pods to be removed in a 15s window. // +listType=atomic // +optional Policies []HPAScalingPolicy `json:"policies,omitempty" listType:"atomic" protobuf:"bytes,2,rep,name=policies"` + + // tolerance is the tolerance on the ratio between the current and desired + // metric value under which no updates are made to the desired number of + // replicas (e.g. 0.01 for 1%). Must be greater than or equal to zero. If not + // set, the default cluster-wide tolerance is applied (by default 10%). + // + // For example, if autoscaling is configured with a memory consumption target of 100Mi, + // and scale-down and scale-up tolerances of 5% and 1% respectively, scaling will be + // triggered when the actual consumption falls below 95Mi or exceeds 101Mi. + // + // This is an alpha field and requires enabling the HPAConfigurableTolerance + // feature gate. + // + // +featureGate=HPAConfigurableTolerance + // +optional + Tolerance *resource.Quantity `json:"tolerance,omitempty" protobuf:"bytes,4,opt,name=tolerance"` } // HPAScalingPolicyType is the type of the policy which could be used while making scaling decisions. diff --git a/go-controller/vendor/k8s.io/api/autoscaling/v2/types_swagger_doc_generated.go b/go-controller/vendor/k8s.io/api/autoscaling/v2/types_swagger_doc_generated.go index 649cd04a03..017fefcde7 100644 --- a/go-controller/vendor/k8s.io/api/autoscaling/v2/types_swagger_doc_generated.go +++ b/go-controller/vendor/k8s.io/api/autoscaling/v2/types_swagger_doc_generated.go @@ -92,10 +92,11 @@ func (HPAScalingPolicy) SwaggerDoc() map[string]string { } var map_HPAScalingRules = map[string]string{ - "": "HPAScalingRules configures the scaling behavior for one direction. These Rules are applied after calculating DesiredReplicas from metrics for the HPA. They can limit the scaling velocity by specifying scaling policies. They can prevent flapping by specifying the stabilization window, so that the number of replicas is not set instantly, instead, the safest value from the stabilization window is chosen.", + "": "HPAScalingRules configures the scaling behavior for one direction via scaling Policy Rules and a configurable metric tolerance.\n\nScaling Policy Rules are applied after calculating DesiredReplicas from metrics for the HPA. They can limit the scaling velocity by specifying scaling policies. They can prevent flapping by specifying the stabilization window, so that the number of replicas is not set instantly, instead, the safest value from the stabilization window is chosen.\n\nThe tolerance is applied to the metric values and prevents scaling too eagerly for small metric variations. (Note that setting a tolerance requires enabling the alpha HPAConfigurableTolerance feature gate.)", "stabilizationWindowSeconds": "stabilizationWindowSeconds is the number of seconds for which past recommendations should be considered while scaling up or scaling down. StabilizationWindowSeconds must be greater than or equal to zero and less than or equal to 3600 (one hour). If not set, use the default values: - For scale up: 0 (i.e. no stabilization is done). - For scale down: 300 (i.e. the stabilization window is 300 seconds long).", "selectPolicy": "selectPolicy is used to specify which policy should be used. If not set, the default value Max is used.", - "policies": "policies is a list of potential scaling polices which can be used during scaling. At least one policy must be specified, otherwise the HPAScalingRules will be discarded as invalid", + "policies": "policies is a list of potential scaling polices which can be used during scaling. If not set, use the default values: - For scale up: allow doubling the number of pods, or an absolute change of 4 pods in a 15s window. - For scale down: allow all pods to be removed in a 15s window.", + "tolerance": "tolerance is the tolerance on the ratio between the current and desired metric value under which no updates are made to the desired number of replicas (e.g. 0.01 for 1%). Must be greater than or equal to zero. If not set, the default cluster-wide tolerance is applied (by default 10%).\n\nFor example, if autoscaling is configured with a memory consumption target of 100Mi, and scale-down and scale-up tolerances of 5% and 1% respectively, scaling will be triggered when the actual consumption falls below 95Mi or exceeds 101Mi.\n\nThis is an alpha field and requires enabling the HPAConfigurableTolerance feature gate.", } func (HPAScalingRules) SwaggerDoc() map[string]string { diff --git a/go-controller/vendor/k8s.io/api/autoscaling/v2/zz_generated.deepcopy.go b/go-controller/vendor/k8s.io/api/autoscaling/v2/zz_generated.deepcopy.go index 125708d6fd..5fbcf9f807 100644 --- a/go-controller/vendor/k8s.io/api/autoscaling/v2/zz_generated.deepcopy.go +++ b/go-controller/vendor/k8s.io/api/autoscaling/v2/zz_generated.deepcopy.go @@ -146,6 +146,11 @@ func (in *HPAScalingRules) DeepCopyInto(out *HPAScalingRules) { *out = make([]HPAScalingPolicy, len(*in)) copy(*out, *in) } + if in.Tolerance != nil { + in, out := &in.Tolerance, &out.Tolerance + x := (*in).DeepCopy() + *out = &x + } return } diff --git a/go-controller/vendor/k8s.io/api/autoscaling/v2beta1/doc.go b/go-controller/vendor/k8s.io/api/autoscaling/v2beta1/doc.go index 25ca507bba..eac92e86e8 100644 --- a/go-controller/vendor/k8s.io/api/autoscaling/v2beta1/doc.go +++ b/go-controller/vendor/k8s.io/api/autoscaling/v2beta1/doc.go @@ -19,4 +19,4 @@ limitations under the License. // +k8s:openapi-gen=true // +k8s:prerelease-lifecycle-gen=true -package v2beta1 // import "k8s.io/api/autoscaling/v2beta1" +package v2beta1 diff --git a/go-controller/vendor/k8s.io/api/autoscaling/v2beta2/doc.go b/go-controller/vendor/k8s.io/api/autoscaling/v2beta2/doc.go index 76fb0aff87..1500372978 100644 --- a/go-controller/vendor/k8s.io/api/autoscaling/v2beta2/doc.go +++ b/go-controller/vendor/k8s.io/api/autoscaling/v2beta2/doc.go @@ -19,4 +19,4 @@ limitations under the License. // +k8s:openapi-gen=true // +k8s:prerelease-lifecycle-gen=true -package v2beta2 // import "k8s.io/api/autoscaling/v2beta2" +package v2beta2 diff --git a/go-controller/vendor/k8s.io/api/batch/v1/doc.go b/go-controller/vendor/k8s.io/api/batch/v1/doc.go index cb5cbb6002..69088e2c5b 100644 --- a/go-controller/vendor/k8s.io/api/batch/v1/doc.go +++ b/go-controller/vendor/k8s.io/api/batch/v1/doc.go @@ -18,4 +18,4 @@ limitations under the License. // +k8s:protobuf-gen=package // +k8s:openapi-gen=true // +k8s:prerelease-lifecycle-gen=true -package v1 // import "k8s.io/api/batch/v1" +package v1 diff --git a/go-controller/vendor/k8s.io/api/batch/v1/generated.proto b/go-controller/vendor/k8s.io/api/batch/v1/generated.proto index 361ebdca12..d3aeae0adb 100644 --- a/go-controller/vendor/k8s.io/api/batch/v1/generated.proto +++ b/go-controller/vendor/k8s.io/api/batch/v1/generated.proto @@ -222,8 +222,6 @@ message JobSpec { // When the field is specified, it must be immutable and works only for the Indexed Jobs. // Once the Job meets the SuccessPolicy, the lingering pods are terminated. // - // This field is beta-level. To use this field, you must enable the - // `JobSuccessPolicy` feature gate (enabled by default). // +optional optional SuccessPolicy successPolicy = 16; @@ -238,8 +236,6 @@ message JobSpec { // batch.kubernetes.io/job-index-failure-count annotation. It can only // be set when Job's completionMode=Indexed, and the Pod's restart // policy is Never. The field is immutable. - // This field is beta-level. It can be used when the `JobBackoffLimitPerIndex` - // feature gate is enabled (enabled by default). // +optional optional int32 backoffLimitPerIndex = 12; @@ -251,8 +247,6 @@ message JobSpec { // It can only be specified when backoffLimitPerIndex is set. // It can be null or up to completions. It is required and must be // less than or equal to 10^4 when is completions greater than 10^5. - // This field is beta-level. It can be used when the `JobBackoffLimitPerIndex` - // feature gate is enabled (enabled by default). // +optional optional int32 maxFailedIndexes = 13; @@ -442,8 +436,6 @@ message JobStatus { // represented as "1,3-5,7". // The set of failed indexes cannot overlap with the set of completed indexes. // - // This field is beta-level. It can be used when the `JobBackoffLimitPerIndex` - // feature gate is enabled (enabled by default). // +optional optional string failedIndexes = 10; @@ -554,8 +546,6 @@ message PodFailurePolicyRule { // running pods are terminated. // - FailIndex: indicates that the pod's index is marked as Failed and will // not be restarted. - // This value is beta-level. It can be used when the - // `JobBackoffLimitPerIndex` feature gate is enabled (enabled by default). // - Ignore: indicates that the counter towards the .backoffLimit is not // incremented and a replacement pod is created. // - Count: indicates that the pod is handled in the default way - the diff --git a/go-controller/vendor/k8s.io/api/batch/v1/types.go b/go-controller/vendor/k8s.io/api/batch/v1/types.go index 8e9a761b95..6c0007c21e 100644 --- a/go-controller/vendor/k8s.io/api/batch/v1/types.go +++ b/go-controller/vendor/k8s.io/api/batch/v1/types.go @@ -128,7 +128,6 @@ const ( // This is an action which might be taken on a pod failure - mark the // Job's index as failed to avoid restarts within this index. This action // can only be used when backoffLimitPerIndex is set. - // This value is beta-level. PodFailurePolicyActionFailIndex PodFailurePolicyAction = "FailIndex" // This is an action which might be taken on a pod failure - the counter towards @@ -223,8 +222,6 @@ type PodFailurePolicyRule struct { // running pods are terminated. // - FailIndex: indicates that the pod's index is marked as Failed and will // not be restarted. - // This value is beta-level. It can be used when the - // `JobBackoffLimitPerIndex` feature gate is enabled (enabled by default). // - Ignore: indicates that the counter towards the .backoffLimit is not // incremented and a replacement pod is created. // - Count: indicates that the pod is handled in the default way - the @@ -346,8 +343,6 @@ type JobSpec struct { // When the field is specified, it must be immutable and works only for the Indexed Jobs. // Once the Job meets the SuccessPolicy, the lingering pods are terminated. // - // This field is beta-level. To use this field, you must enable the - // `JobSuccessPolicy` feature gate (enabled by default). // +optional SuccessPolicy *SuccessPolicy `json:"successPolicy,omitempty" protobuf:"bytes,16,opt,name=successPolicy"` @@ -362,8 +357,6 @@ type JobSpec struct { // batch.kubernetes.io/job-index-failure-count annotation. It can only // be set when Job's completionMode=Indexed, and the Pod's restart // policy is Never. The field is immutable. - // This field is beta-level. It can be used when the `JobBackoffLimitPerIndex` - // feature gate is enabled (enabled by default). // +optional BackoffLimitPerIndex *int32 `json:"backoffLimitPerIndex,omitempty" protobuf:"varint,12,opt,name=backoffLimitPerIndex"` @@ -375,8 +368,6 @@ type JobSpec struct { // It can only be specified when backoffLimitPerIndex is set. // It can be null or up to completions. It is required and must be // less than or equal to 10^4 when is completions greater than 10^5. - // This field is beta-level. It can be used when the `JobBackoffLimitPerIndex` - // feature gate is enabled (enabled by default). // +optional MaxFailedIndexes *int32 `json:"maxFailedIndexes,omitempty" protobuf:"varint,13,opt,name=maxFailedIndexes"` @@ -571,8 +562,6 @@ type JobStatus struct { // represented as "1,3-5,7". // The set of failed indexes cannot overlap with the set of completed indexes. // - // This field is beta-level. It can be used when the `JobBackoffLimitPerIndex` - // feature gate is enabled (enabled by default). // +optional FailedIndexes *string `json:"failedIndexes,omitempty" protobuf:"bytes,10,opt,name=failedIndexes"` @@ -647,13 +636,9 @@ const ( JobReasonFailedIndexes string = "FailedIndexes" // JobReasonSuccessPolicy reason indicates a SuccessCriteriaMet condition is added due to // a Job met successPolicy. - // https://kep.k8s.io/3998 - // This is currently a beta field. JobReasonSuccessPolicy string = "SuccessPolicy" // JobReasonCompletionsReached reason indicates a SuccessCriteriaMet condition is added due to // a number of succeeded Job pods met completions. - // - https://kep.k8s.io/3998 - // This is currently a beta field. JobReasonCompletionsReached string = "CompletionsReached" ) diff --git a/go-controller/vendor/k8s.io/api/batch/v1/types_swagger_doc_generated.go b/go-controller/vendor/k8s.io/api/batch/v1/types_swagger_doc_generated.go index 893f3371f0..ffd4e4f5fe 100644 --- a/go-controller/vendor/k8s.io/api/batch/v1/types_swagger_doc_generated.go +++ b/go-controller/vendor/k8s.io/api/batch/v1/types_swagger_doc_generated.go @@ -116,10 +116,10 @@ var map_JobSpec = map[string]string{ "completions": "Specifies the desired number of successfully finished pods the job should be run with. Setting to null means that the success of any pod signals the success of all pods, and allows parallelism to have any positive value. Setting to 1 means that parallelism is limited to 1 and the success of that pod signals the success of the job. More info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/", "activeDeadlineSeconds": "Specifies the duration in seconds relative to the startTime that the job may be continuously active before the system tries to terminate it; value must be positive integer. If a Job is suspended (at creation or through an update), this timer will effectively be stopped and reset when the Job is resumed again.", "podFailurePolicy": "Specifies the policy of handling failed pods. In particular, it allows to specify the set of actions and conditions which need to be satisfied to take the associated action. If empty, the default behaviour applies - the counter of failed pods, represented by the jobs's .status.failed field, is incremented and it is checked against the backoffLimit. This field cannot be used in combination with restartPolicy=OnFailure.", - "successPolicy": "successPolicy specifies the policy when the Job can be declared as succeeded. If empty, the default behavior applies - the Job is declared as succeeded only when the number of succeeded pods equals to the completions. When the field is specified, it must be immutable and works only for the Indexed Jobs. Once the Job meets the SuccessPolicy, the lingering pods are terminated.\n\nThis field is beta-level. To use this field, you must enable the `JobSuccessPolicy` feature gate (enabled by default).", + "successPolicy": "successPolicy specifies the policy when the Job can be declared as succeeded. If empty, the default behavior applies - the Job is declared as succeeded only when the number of succeeded pods equals to the completions. When the field is specified, it must be immutable and works only for the Indexed Jobs. Once the Job meets the SuccessPolicy, the lingering pods are terminated.", "backoffLimit": "Specifies the number of retries before marking this job failed. Defaults to 6", - "backoffLimitPerIndex": "Specifies the limit for the number of retries within an index before marking this index as failed. When enabled the number of failures per index is kept in the pod's batch.kubernetes.io/job-index-failure-count annotation. It can only be set when Job's completionMode=Indexed, and the Pod's restart policy is Never. The field is immutable. This field is beta-level. It can be used when the `JobBackoffLimitPerIndex` feature gate is enabled (enabled by default).", - "maxFailedIndexes": "Specifies the maximal number of failed indexes before marking the Job as failed, when backoffLimitPerIndex is set. Once the number of failed indexes exceeds this number the entire Job is marked as Failed and its execution is terminated. When left as null the job continues execution of all of its indexes and is marked with the `Complete` Job condition. It can only be specified when backoffLimitPerIndex is set. It can be null or up to completions. It is required and must be less than or equal to 10^4 when is completions greater than 10^5. This field is beta-level. It can be used when the `JobBackoffLimitPerIndex` feature gate is enabled (enabled by default).", + "backoffLimitPerIndex": "Specifies the limit for the number of retries within an index before marking this index as failed. When enabled the number of failures per index is kept in the pod's batch.kubernetes.io/job-index-failure-count annotation. It can only be set when Job's completionMode=Indexed, and the Pod's restart policy is Never. The field is immutable.", + "maxFailedIndexes": "Specifies the maximal number of failed indexes before marking the Job as failed, when backoffLimitPerIndex is set. Once the number of failed indexes exceeds this number the entire Job is marked as Failed and its execution is terminated. When left as null the job continues execution of all of its indexes and is marked with the `Complete` Job condition. It can only be specified when backoffLimitPerIndex is set. It can be null or up to completions. It is required and must be less than or equal to 10^4 when is completions greater than 10^5.", "selector": "A label query over pods that should match the pod count. Normally, the system sets this field for you. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors", "manualSelector": "manualSelector controls generation of pod labels and pod selectors. Leave `manualSelector` unset unless you are certain what you are doing. When false or unset, the system pick labels unique to this job and appends those labels to the pod template. When true, the user is responsible for picking unique labels and specifying the selector. Failure to pick a unique label may cause this and other jobs to not function correctly. However, You may see `manualSelector=true` in jobs that were created with the old `extensions/v1beta1` API. More info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/#specifying-your-own-pod-selector", "template": "Describes the pod that will be created when executing a job. The only allowed template.spec.restartPolicy values are \"Never\" or \"OnFailure\". More info: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/", @@ -144,7 +144,7 @@ var map_JobStatus = map[string]string{ "failed": "The number of pods which reached phase Failed. The value increases monotonically.", "terminating": "The number of pods which are terminating (in phase Pending or Running and have a deletionTimestamp).\n\nThis field is beta-level. The job controller populates the field when the feature gate JobPodReplacementPolicy is enabled (enabled by default).", "completedIndexes": "completedIndexes holds the completed indexes when .spec.completionMode = \"Indexed\" in a text format. The indexes are represented as decimal integers separated by commas. The numbers are listed in increasing order. Three or more consecutive numbers are compressed and represented by the first and last element of the series, separated by a hyphen. For example, if the completed indexes are 1, 3, 4, 5 and 7, they are represented as \"1,3-5,7\".", - "failedIndexes": "FailedIndexes holds the failed indexes when spec.backoffLimitPerIndex is set. The indexes are represented in the text format analogous as for the `completedIndexes` field, ie. they are kept as decimal integers separated by commas. The numbers are listed in increasing order. Three or more consecutive numbers are compressed and represented by the first and last element of the series, separated by a hyphen. For example, if the failed indexes are 1, 3, 4, 5 and 7, they are represented as \"1,3-5,7\". The set of failed indexes cannot overlap with the set of completed indexes.\n\nThis field is beta-level. It can be used when the `JobBackoffLimitPerIndex` feature gate is enabled (enabled by default).", + "failedIndexes": "FailedIndexes holds the failed indexes when spec.backoffLimitPerIndex is set. The indexes are represented in the text format analogous as for the `completedIndexes` field, ie. they are kept as decimal integers separated by commas. The numbers are listed in increasing order. Three or more consecutive numbers are compressed and represented by the first and last element of the series, separated by a hyphen. For example, if the failed indexes are 1, 3, 4, 5 and 7, they are represented as \"1,3-5,7\". The set of failed indexes cannot overlap with the set of completed indexes.", "uncountedTerminatedPods": "uncountedTerminatedPods holds the UIDs of Pods that have terminated but the job controller hasn't yet accounted for in the status counters.\n\nThe job controller creates pods with a finalizer. When a pod terminates (succeeded or failed), the controller does three steps to account for it in the job status:\n\n1. Add the pod UID to the arrays in this field. 2. Remove the pod finalizer. 3. Remove the pod UID from the arrays while increasing the corresponding\n counter.\n\nOld jobs might not be tracked using this field, in which case the field remains null. The structure is empty for finished jobs.", "ready": "The number of active pods which have a Ready condition and are not terminating (without a deletionTimestamp).", } @@ -195,7 +195,7 @@ func (PodFailurePolicyOnPodConditionsPattern) SwaggerDoc() map[string]string { var map_PodFailurePolicyRule = map[string]string{ "": "PodFailurePolicyRule describes how a pod failure is handled when the requirements are met. One of onExitCodes and onPodConditions, but not both, can be used in each rule.", - "action": "Specifies the action taken on a pod failure when the requirements are satisfied. Possible values are:\n\n- FailJob: indicates that the pod's job is marked as Failed and all\n running pods are terminated.\n- FailIndex: indicates that the pod's index is marked as Failed and will\n not be restarted.\n This value is beta-level. It can be used when the\n `JobBackoffLimitPerIndex` feature gate is enabled (enabled by default).\n- Ignore: indicates that the counter towards the .backoffLimit is not\n incremented and a replacement pod is created.\n- Count: indicates that the pod is handled in the default way - the\n counter towards the .backoffLimit is incremented.\nAdditional values are considered to be added in the future. Clients should react to an unknown action by skipping the rule.", + "action": "Specifies the action taken on a pod failure when the requirements are satisfied. Possible values are:\n\n- FailJob: indicates that the pod's job is marked as Failed and all\n running pods are terminated.\n- FailIndex: indicates that the pod's index is marked as Failed and will\n not be restarted.\n- Ignore: indicates that the counter towards the .backoffLimit is not\n incremented and a replacement pod is created.\n- Count: indicates that the pod is handled in the default way - the\n counter towards the .backoffLimit is incremented.\nAdditional values are considered to be added in the future. Clients should react to an unknown action by skipping the rule.", "onExitCodes": "Represents the requirement on the container exit codes.", "onPodConditions": "Represents the requirement on the pod conditions. The requirement is represented as a list of pod condition patterns. The requirement is satisfied if at least one pattern matches an actual pod condition. At most 20 elements are allowed.", } diff --git a/go-controller/vendor/k8s.io/api/batch/v1beta1/doc.go b/go-controller/vendor/k8s.io/api/batch/v1beta1/doc.go index cb2572f5da..3430d6939d 100644 --- a/go-controller/vendor/k8s.io/api/batch/v1beta1/doc.go +++ b/go-controller/vendor/k8s.io/api/batch/v1beta1/doc.go @@ -19,4 +19,4 @@ limitations under the License. // +k8s:openapi-gen=true // +k8s:prerelease-lifecycle-gen=true -package v1beta1 // import "k8s.io/api/batch/v1beta1" +package v1beta1 diff --git a/go-controller/vendor/k8s.io/api/certificates/v1/doc.go b/go-controller/vendor/k8s.io/api/certificates/v1/doc.go index 78434478e8..6c16fc29b8 100644 --- a/go-controller/vendor/k8s.io/api/certificates/v1/doc.go +++ b/go-controller/vendor/k8s.io/api/certificates/v1/doc.go @@ -20,4 +20,4 @@ limitations under the License. // +k8s:prerelease-lifecycle-gen=true // +groupName=certificates.k8s.io -package v1 // import "k8s.io/api/certificates/v1" +package v1 diff --git a/go-controller/vendor/k8s.io/api/certificates/v1alpha1/doc.go b/go-controller/vendor/k8s.io/api/certificates/v1alpha1/doc.go index d83d0e8207..01481df8e5 100644 --- a/go-controller/vendor/k8s.io/api/certificates/v1alpha1/doc.go +++ b/go-controller/vendor/k8s.io/api/certificates/v1alpha1/doc.go @@ -21,4 +21,4 @@ limitations under the License. // +groupName=certificates.k8s.io -package v1alpha1 // import "k8s.io/api/certificates/v1alpha1" +package v1alpha1 diff --git a/go-controller/vendor/k8s.io/api/certificates/v1beta1/doc.go b/go-controller/vendor/k8s.io/api/certificates/v1beta1/doc.go index 1165518c67..81608a554c 100644 --- a/go-controller/vendor/k8s.io/api/certificates/v1beta1/doc.go +++ b/go-controller/vendor/k8s.io/api/certificates/v1beta1/doc.go @@ -21,4 +21,4 @@ limitations under the License. // +groupName=certificates.k8s.io -package v1beta1 // import "k8s.io/api/certificates/v1beta1" +package v1beta1 diff --git a/go-controller/vendor/k8s.io/api/certificates/v1beta1/generated.pb.go b/go-controller/vendor/k8s.io/api/certificates/v1beta1/generated.pb.go index b6d8ab3f59..199a54496a 100644 --- a/go-controller/vendor/k8s.io/api/certificates/v1beta1/generated.pb.go +++ b/go-controller/vendor/k8s.io/api/certificates/v1beta1/generated.pb.go @@ -186,10 +186,94 @@ func (m *CertificateSigningRequestStatus) XXX_DiscardUnknown() { var xxx_messageInfo_CertificateSigningRequestStatus proto.InternalMessageInfo +func (m *ClusterTrustBundle) Reset() { *m = ClusterTrustBundle{} } +func (*ClusterTrustBundle) ProtoMessage() {} +func (*ClusterTrustBundle) Descriptor() ([]byte, []int) { + return fileDescriptor_6529c11a462c48a5, []int{5} +} +func (m *ClusterTrustBundle) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ClusterTrustBundle) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ClusterTrustBundle) XXX_Merge(src proto.Message) { + xxx_messageInfo_ClusterTrustBundle.Merge(m, src) +} +func (m *ClusterTrustBundle) XXX_Size() int { + return m.Size() +} +func (m *ClusterTrustBundle) XXX_DiscardUnknown() { + xxx_messageInfo_ClusterTrustBundle.DiscardUnknown(m) +} + +var xxx_messageInfo_ClusterTrustBundle proto.InternalMessageInfo + +func (m *ClusterTrustBundleList) Reset() { *m = ClusterTrustBundleList{} } +func (*ClusterTrustBundleList) ProtoMessage() {} +func (*ClusterTrustBundleList) Descriptor() ([]byte, []int) { + return fileDescriptor_6529c11a462c48a5, []int{6} +} +func (m *ClusterTrustBundleList) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ClusterTrustBundleList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ClusterTrustBundleList) XXX_Merge(src proto.Message) { + xxx_messageInfo_ClusterTrustBundleList.Merge(m, src) +} +func (m *ClusterTrustBundleList) XXX_Size() int { + return m.Size() +} +func (m *ClusterTrustBundleList) XXX_DiscardUnknown() { + xxx_messageInfo_ClusterTrustBundleList.DiscardUnknown(m) +} + +var xxx_messageInfo_ClusterTrustBundleList proto.InternalMessageInfo + +func (m *ClusterTrustBundleSpec) Reset() { *m = ClusterTrustBundleSpec{} } +func (*ClusterTrustBundleSpec) ProtoMessage() {} +func (*ClusterTrustBundleSpec) Descriptor() ([]byte, []int) { + return fileDescriptor_6529c11a462c48a5, []int{7} +} +func (m *ClusterTrustBundleSpec) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ClusterTrustBundleSpec) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ClusterTrustBundleSpec) XXX_Merge(src proto.Message) { + xxx_messageInfo_ClusterTrustBundleSpec.Merge(m, src) +} +func (m *ClusterTrustBundleSpec) XXX_Size() int { + return m.Size() +} +func (m *ClusterTrustBundleSpec) XXX_DiscardUnknown() { + xxx_messageInfo_ClusterTrustBundleSpec.DiscardUnknown(m) +} + +var xxx_messageInfo_ClusterTrustBundleSpec proto.InternalMessageInfo + func (m *ExtraValue) Reset() { *m = ExtraValue{} } func (*ExtraValue) ProtoMessage() {} func (*ExtraValue) Descriptor() ([]byte, []int) { - return fileDescriptor_6529c11a462c48a5, []int{5} + return fileDescriptor_6529c11a462c48a5, []int{8} } func (m *ExtraValue) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -221,6 +305,9 @@ func init() { proto.RegisterType((*CertificateSigningRequestSpec)(nil), "k8s.io.api.certificates.v1beta1.CertificateSigningRequestSpec") proto.RegisterMapType((map[string]ExtraValue)(nil), "k8s.io.api.certificates.v1beta1.CertificateSigningRequestSpec.ExtraEntry") proto.RegisterType((*CertificateSigningRequestStatus)(nil), "k8s.io.api.certificates.v1beta1.CertificateSigningRequestStatus") + proto.RegisterType((*ClusterTrustBundle)(nil), "k8s.io.api.certificates.v1beta1.ClusterTrustBundle") + proto.RegisterType((*ClusterTrustBundleList)(nil), "k8s.io.api.certificates.v1beta1.ClusterTrustBundleList") + proto.RegisterType((*ClusterTrustBundleSpec)(nil), "k8s.io.api.certificates.v1beta1.ClusterTrustBundleSpec") proto.RegisterType((*ExtraValue)(nil), "k8s.io.api.certificates.v1beta1.ExtraValue") } @@ -229,64 +316,69 @@ func init() { } var fileDescriptor_6529c11a462c48a5 = []byte{ - // 901 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0x4d, 0x6f, 0x1b, 0x45, - 0x18, 0xf6, 0xc6, 0x1f, 0xb1, 0xc7, 0x21, 0x6d, 0x47, 0x50, 0x2d, 0x96, 0xea, 0xb5, 0x56, 0x80, - 0xc2, 0xd7, 0x2c, 0xa9, 0x2a, 0x88, 0x72, 0x40, 0xb0, 0x21, 0x42, 0x11, 0x29, 0x48, 0x93, 0x84, - 0x03, 0x42, 0xa2, 0x93, 0xf5, 0xdb, 0xcd, 0x34, 0xdd, 0x0f, 0x76, 0x66, 0x4d, 0x7d, 0xeb, 0x4f, - 0xe0, 0xc8, 0x91, 0xff, 0xc0, 0x9f, 0x08, 0x07, 0xa4, 0x1e, 0x7b, 0x40, 0x16, 0x71, 0xff, 0x45, - 0x4e, 0x68, 0x66, 0xc7, 0x6b, 0xc7, 0x4e, 0x70, 0x69, 0x6f, 0x3b, 0xcf, 0xbc, 0xcf, 0xf3, 0xbc, - 0xf3, 0xce, 0xfb, 0x8e, 0x8d, 0xbc, 0xd3, 0x2d, 0x41, 0x78, 0xe2, 0xb1, 0x94, 0x7b, 0x01, 0x64, - 0x92, 0x3f, 0xe4, 0x01, 0x93, 0x20, 0xbc, 0xc1, 0xe6, 0x31, 0x48, 0xb6, 0xe9, 0x85, 0x10, 0x43, - 0xc6, 0x24, 0xf4, 0x49, 0x9a, 0x25, 0x32, 0xc1, 0x4e, 0x41, 0x20, 0x2c, 0xe5, 0x64, 0x96, 0x40, - 0x0c, 0xa1, 0xf3, 0x71, 0xc8, 0xe5, 0x49, 0x7e, 0x4c, 0x82, 0x24, 0xf2, 0xc2, 0x24, 0x4c, 0x3c, - 0xcd, 0x3b, 0xce, 0x1f, 0xea, 0x95, 0x5e, 0xe8, 0xaf, 0x42, 0xaf, 0xe3, 0xce, 0x26, 0x90, 0x64, - 0xe0, 0x0d, 0x16, 0x3c, 0x3b, 0xf7, 0xa6, 0x31, 0x11, 0x0b, 0x4e, 0x78, 0x0c, 0xd9, 0xd0, 0x4b, - 0x4f, 0x43, 0x05, 0x08, 0x2f, 0x02, 0xc9, 0xae, 0x62, 0x79, 0xd7, 0xb1, 0xb2, 0x3c, 0x96, 0x3c, - 0x82, 0x05, 0xc2, 0xa7, 0xcb, 0x08, 0x22, 0x38, 0x81, 0x88, 0xcd, 0xf3, 0xdc, 0x3f, 0x57, 0xd0, - 0xdb, 0x3b, 0xd3, 0x52, 0x1c, 0xf0, 0x30, 0xe6, 0x71, 0x48, 0xe1, 0xe7, 0x1c, 0x84, 0xc4, 0x0f, - 0x50, 0x53, 0x65, 0xd8, 0x67, 0x92, 0xd9, 0x56, 0xcf, 0xda, 0x68, 0xdf, 0xfd, 0x84, 0x4c, 0x6b, - 0x58, 0x1a, 0x91, 0xf4, 0x34, 0x54, 0x80, 0x20, 0x2a, 0x9a, 0x0c, 0x36, 0xc9, 0x77, 0xc7, 0x8f, - 0x20, 0x90, 0xf7, 0x41, 0x32, 0x1f, 0x9f, 0x8d, 0x9c, 0xca, 0x78, 0xe4, 0xa0, 0x29, 0x46, 0x4b, - 0x55, 0xfc, 0x00, 0xd5, 0x44, 0x0a, 0x81, 0xbd, 0xa2, 0xd5, 0x3f, 0x27, 0x4b, 0x6e, 0x88, 0x5c, - 0x9b, 0xeb, 0x41, 0x0a, 0x81, 0xbf, 0x66, 0xbc, 0x6a, 0x6a, 0x45, 0xb5, 0x32, 0x3e, 0x41, 0x0d, - 0x21, 0x99, 0xcc, 0x85, 0x5d, 0xd5, 0x1e, 0x5f, 0xbc, 0x86, 0x87, 0xd6, 0xf1, 0xd7, 0x8d, 0x4b, - 0xa3, 0x58, 0x53, 0xa3, 0xef, 0xbe, 0xa8, 0x22, 0xf7, 0x5a, 0xee, 0x4e, 0x12, 0xf7, 0xb9, 0xe4, - 0x49, 0x8c, 0xb7, 0x50, 0x4d, 0x0e, 0x53, 0xd0, 0x05, 0x6d, 0xf9, 0xef, 0x4c, 0x52, 0x3e, 0x1c, - 0xa6, 0x70, 0x31, 0x72, 0xde, 0x9c, 0x8f, 0x57, 0x38, 0xd5, 0x0c, 0xbc, 0x5f, 0x1e, 0xa5, 0xa1, - 0xb9, 0xf7, 0x2e, 0x27, 0x72, 0x31, 0x72, 0xae, 0xe8, 0x48, 0x52, 0x2a, 0x5d, 0x4e, 0x17, 0xbf, - 0x87, 0x1a, 0x19, 0x30, 0x91, 0xc4, 0xba, 0xf8, 0xad, 0xe9, 0xb1, 0xa8, 0x46, 0xa9, 0xd9, 0xc5, - 0xef, 0xa3, 0xd5, 0x08, 0x84, 0x60, 0x21, 0xe8, 0x0a, 0xb6, 0xfc, 0x1b, 0x26, 0x70, 0xf5, 0x7e, - 0x01, 0xd3, 0xc9, 0x3e, 0x7e, 0x84, 0xd6, 0x1f, 0x33, 0x21, 0x8f, 0xd2, 0x3e, 0x93, 0x70, 0xc8, - 0x23, 0xb0, 0x6b, 0xba, 0xe6, 0x1f, 0xbc, 0x5c, 0xd7, 0x28, 0x86, 0x7f, 0xdb, 0xa8, 0xaf, 0xef, - 0x5f, 0x52, 0xa2, 0x73, 0xca, 0x78, 0x80, 0xb0, 0x42, 0x0e, 0x33, 0x16, 0x8b, 0xa2, 0x50, 0xca, - 0xaf, 0xfe, 0xbf, 0xfd, 0x3a, 0xc6, 0x0f, 0xef, 0x2f, 0xa8, 0xd1, 0x2b, 0x1c, 0xdc, 0x91, 0x85, - 0xee, 0x5c, 0x7b, 0xcb, 0xfb, 0x5c, 0x48, 0xfc, 0xe3, 0xc2, 0xd4, 0x90, 0x97, 0xcb, 0x47, 0xb1, - 0xf5, 0xcc, 0xdc, 0x34, 0x39, 0x35, 0x27, 0xc8, 0xcc, 0xc4, 0xfc, 0x84, 0xea, 0x5c, 0x42, 0x24, - 0xec, 0x95, 0x5e, 0x75, 0xa3, 0x7d, 0x77, 0xfb, 0xd5, 0xdb, 0xd9, 0x7f, 0xc3, 0xd8, 0xd4, 0xf7, - 0x94, 0x20, 0x2d, 0x74, 0xdd, 0x3f, 0x6a, 0xff, 0x71, 0x40, 0x35, 0x58, 0xf8, 0x5d, 0xb4, 0x9a, - 0x15, 0x4b, 0x7d, 0xbe, 0x35, 0xbf, 0xad, 0xba, 0xc1, 0x44, 0xd0, 0xc9, 0x1e, 0x26, 0x08, 0x09, - 0x1e, 0xc6, 0x90, 0x7d, 0xcb, 0x22, 0xb0, 0x57, 0x8b, 0x26, 0x53, 0x2f, 0xc1, 0x41, 0x89, 0xd2, - 0x99, 0x08, 0xbc, 0x83, 0x6e, 0xc1, 0x93, 0x94, 0x67, 0x4c, 0x37, 0x2b, 0x04, 0x49, 0xdc, 0x17, - 0x76, 0xb3, 0x67, 0x6d, 0xd4, 0xfd, 0xb7, 0xc6, 0x23, 0xe7, 0xd6, 0xee, 0xfc, 0x26, 0x5d, 0x8c, - 0xc7, 0x04, 0x35, 0x72, 0xd5, 0x8b, 0xc2, 0xae, 0xf7, 0xaa, 0x1b, 0x2d, 0xff, 0xb6, 0xea, 0xe8, - 0x23, 0x8d, 0x5c, 0x8c, 0x9c, 0xe6, 0x37, 0x30, 0xd4, 0x0b, 0x6a, 0xa2, 0xf0, 0x47, 0xa8, 0x99, - 0x0b, 0xc8, 0x62, 0x95, 0x62, 0x31, 0x07, 0x65, 0xf1, 0x8f, 0x0c, 0x4e, 0xcb, 0x08, 0x7c, 0x07, - 0x55, 0x73, 0xde, 0x37, 0x73, 0xd0, 0x36, 0x81, 0xd5, 0xa3, 0xbd, 0xaf, 0xa8, 0xc2, 0xb1, 0x8b, - 0x1a, 0x61, 0x96, 0xe4, 0xa9, 0xb0, 0x6b, 0xda, 0x1c, 0x29, 0xf3, 0xaf, 0x35, 0x42, 0xcd, 0x0e, - 0x8e, 0x51, 0x1d, 0x9e, 0xc8, 0x8c, 0xd9, 0x0d, 0x7d, 0x7f, 0x7b, 0xaf, 0xf7, 0xe4, 0x91, 0x5d, - 0xa5, 0xb5, 0x1b, 0xcb, 0x6c, 0x38, 0xbd, 0x4e, 0x8d, 0xd1, 0xc2, 0xa6, 0x03, 0x08, 0x4d, 0x63, - 0xf0, 0x4d, 0x54, 0x3d, 0x85, 0x61, 0xf1, 0xf6, 0x50, 0xf5, 0x89, 0xbf, 0x44, 0xf5, 0x01, 0x7b, - 0x9c, 0x83, 0x79, 0x82, 0x3f, 0x5c, 0x9a, 0x8f, 0x56, 0xfb, 0x5e, 0x51, 0x68, 0xc1, 0xdc, 0x5e, - 0xd9, 0xb2, 0xdc, 0xbf, 0x2c, 0xe4, 0x2c, 0x79, 0x38, 0xf1, 0x2f, 0x08, 0x05, 0x93, 0xc7, 0x48, - 0xd8, 0x96, 0x3e, 0xff, 0xce, 0xab, 0x9f, 0xbf, 0x7c, 0xd8, 0xa6, 0xbf, 0x31, 0x25, 0x24, 0xe8, - 0x8c, 0x15, 0xde, 0x44, 0xed, 0x19, 0x69, 0x7d, 0xd2, 0x35, 0xff, 0xc6, 0x78, 0xe4, 0xb4, 0x67, - 0xc4, 0xe9, 0x6c, 0x8c, 0xfb, 0x99, 0x29, 0x9b, 0x3e, 0x28, 0x76, 0x26, 0x43, 0x67, 0xe9, 0x7b, - 0x6d, 0xcd, 0x0f, 0xcd, 0x76, 0xf3, 0xb7, 0xdf, 0x9d, 0xca, 0xd3, 0xbf, 0x7b, 0x15, 0x7f, 0xf7, - 0xec, 0xbc, 0x5b, 0x79, 0x76, 0xde, 0xad, 0x3c, 0x3f, 0xef, 0x56, 0x9e, 0x8e, 0xbb, 0xd6, 0xd9, - 0xb8, 0x6b, 0x3d, 0x1b, 0x77, 0xad, 0xe7, 0xe3, 0xae, 0xf5, 0xcf, 0xb8, 0x6b, 0xfd, 0xfa, 0xa2, - 0x5b, 0xf9, 0xc1, 0x59, 0xf2, 0xdf, 0xe5, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x35, 0x2f, 0x11, - 0xe8, 0xdd, 0x08, 0x00, 0x00, + // 991 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0x4f, 0x6f, 0xe3, 0x44, + 0x14, 0x8f, 0x9b, 0x3f, 0x4d, 0x26, 0xa5, 0xbb, 0x3b, 0x40, 0x65, 0x22, 0x6d, 0x1c, 0x59, 0x80, + 0xca, 0x3f, 0x9b, 0x96, 0x85, 0xad, 0x7a, 0x40, 0xe0, 0x50, 0xa1, 0x8a, 0x2e, 0x48, 0xd3, 0x16, + 0x01, 0x42, 0x62, 0xa7, 0xce, 0x5b, 0xd7, 0xdb, 0xc6, 0x36, 0x9e, 0x71, 0xd8, 0xdc, 0x56, 0xe2, + 0x0b, 0x70, 0xe4, 0xc8, 0x77, 0xe0, 0x4b, 0x94, 0x03, 0x52, 0xb9, 0xed, 0x01, 0x45, 0x34, 0xfb, + 0x2d, 0x7a, 0x42, 0x33, 0x9e, 0x38, 0x4e, 0xd2, 0x90, 0xa5, 0x2b, 0xed, 0x2d, 0xf3, 0xe6, 0xfd, + 0x7e, 0xbf, 0xf7, 0x9e, 0xdf, 0x7b, 0x13, 0x64, 0x9f, 0x6c, 0x31, 0xcb, 0x0f, 0x6d, 0x1a, 0xf9, + 0xb6, 0x0b, 0x31, 0xf7, 0x1f, 0xf8, 0x2e, 0xe5, 0xc0, 0xec, 0xde, 0xc6, 0x11, 0x70, 0xba, 0x61, + 0x7b, 0x10, 0x40, 0x4c, 0x39, 0x74, 0xac, 0x28, 0x0e, 0x79, 0x88, 0x8d, 0x14, 0x60, 0xd1, 0xc8, + 0xb7, 0xf2, 0x00, 0x4b, 0x01, 0x1a, 0xef, 0x79, 0x3e, 0x3f, 0x4e, 0x8e, 0x2c, 0x37, 0xec, 0xda, + 0x5e, 0xe8, 0x85, 0xb6, 0xc4, 0x1d, 0x25, 0x0f, 0xe4, 0x49, 0x1e, 0xe4, 0xaf, 0x94, 0xaf, 0x61, + 0xe6, 0x03, 0x08, 0x63, 0xb0, 0x7b, 0x33, 0x9a, 0x8d, 0x3b, 0x63, 0x9f, 0x2e, 0x75, 0x8f, 0xfd, + 0x00, 0xe2, 0xbe, 0x1d, 0x9d, 0x78, 0xc2, 0xc0, 0xec, 0x2e, 0x70, 0x7a, 0x15, 0xca, 0x9e, 0x87, + 0x8a, 0x93, 0x80, 0xfb, 0x5d, 0x98, 0x01, 0x7c, 0xb4, 0x08, 0xc0, 0xdc, 0x63, 0xe8, 0xd2, 0x69, + 0x9c, 0xf9, 0xc7, 0x12, 0x7a, 0xad, 0x3d, 0x2e, 0xc5, 0xbe, 0xef, 0x05, 0x7e, 0xe0, 0x11, 0xf8, + 0x31, 0x01, 0xc6, 0xf1, 0x7d, 0x54, 0x15, 0x11, 0x76, 0x28, 0xa7, 0xba, 0xd6, 0xd2, 0xd6, 0xeb, + 0x9b, 0xef, 0x5b, 0xe3, 0x1a, 0x66, 0x42, 0x56, 0x74, 0xe2, 0x09, 0x03, 0xb3, 0x84, 0xb7, 0xd5, + 0xdb, 0xb0, 0xbe, 0x3a, 0x7a, 0x08, 0x2e, 0xbf, 0x07, 0x9c, 0x3a, 0xf8, 0x6c, 0x60, 0x14, 0x86, + 0x03, 0x03, 0x8d, 0x6d, 0x24, 0x63, 0xc5, 0xf7, 0x51, 0x89, 0x45, 0xe0, 0xea, 0x4b, 0x92, 0xfd, + 0x63, 0x6b, 0xc1, 0x17, 0xb2, 0xe6, 0xc6, 0xba, 0x1f, 0x81, 0xeb, 0xac, 0x28, 0xad, 0x92, 0x38, + 0x11, 0xc9, 0x8c, 0x8f, 0x51, 0x85, 0x71, 0xca, 0x13, 0xa6, 0x17, 0xa5, 0xc6, 0x27, 0xcf, 0xa1, + 0x21, 0x79, 0x9c, 0x55, 0xa5, 0x52, 0x49, 0xcf, 0x44, 0xf1, 0x9b, 0x4f, 0x8b, 0xc8, 0x9c, 0x8b, + 0x6d, 0x87, 0x41, 0xc7, 0xe7, 0x7e, 0x18, 0xe0, 0x2d, 0x54, 0xe2, 0xfd, 0x08, 0x64, 0x41, 0x6b, + 0xce, 0xeb, 0xa3, 0x90, 0x0f, 0xfa, 0x11, 0x5c, 0x0e, 0x8c, 0x57, 0xa6, 0xfd, 0x85, 0x9d, 0x48, + 0x04, 0xde, 0xcb, 0x52, 0xa9, 0x48, 0xec, 0x9d, 0xc9, 0x40, 0x2e, 0x07, 0xc6, 0x15, 0x1d, 0x69, + 0x65, 0x4c, 0x93, 0xe1, 0xe2, 0x37, 0x51, 0x25, 0x06, 0xca, 0xc2, 0x40, 0x16, 0xbf, 0x36, 0x4e, + 0x8b, 0x48, 0x2b, 0x51, 0xb7, 0xf8, 0x2d, 0xb4, 0xdc, 0x05, 0xc6, 0xa8, 0x07, 0xb2, 0x82, 0x35, + 0xe7, 0x86, 0x72, 0x5c, 0xbe, 0x97, 0x9a, 0xc9, 0xe8, 0x1e, 0x3f, 0x44, 0xab, 0xa7, 0x94, 0xf1, + 0xc3, 0xa8, 0x43, 0x39, 0x1c, 0xf8, 0x5d, 0xd0, 0x4b, 0xb2, 0xe6, 0x6f, 0x3f, 0x5b, 0xd7, 0x08, + 0x84, 0xb3, 0xa6, 0xd8, 0x57, 0xf7, 0x26, 0x98, 0xc8, 0x14, 0x33, 0xee, 0x21, 0x2c, 0x2c, 0x07, + 0x31, 0x0d, 0x58, 0x5a, 0x28, 0xa1, 0x57, 0xfe, 0xdf, 0x7a, 0x0d, 0xa5, 0x87, 0xf7, 0x66, 0xd8, + 0xc8, 0x15, 0x0a, 0xe6, 0x40, 0x43, 0xb7, 0xe7, 0x7e, 0xe5, 0x3d, 0x9f, 0x71, 0xfc, 0xfd, 0xcc, + 0xd4, 0x58, 0xcf, 0x16, 0x8f, 0x40, 0xcb, 0x99, 0xb9, 0xa9, 0x62, 0xaa, 0x8e, 0x2c, 0xb9, 0x89, + 0xf9, 0x01, 0x95, 0x7d, 0x0e, 0x5d, 0xa6, 0x2f, 0xb5, 0x8a, 0xeb, 0xf5, 0xcd, 0xed, 0xeb, 0xb7, + 0xb3, 0xf3, 0x92, 0x92, 0x29, 0xef, 0x0a, 0x42, 0x92, 0xf2, 0x9a, 0xbf, 0x97, 0xfe, 0x23, 0x41, + 0x31, 0x58, 0xf8, 0x0d, 0xb4, 0x1c, 0xa7, 0x47, 0x99, 0xdf, 0x8a, 0x53, 0x17, 0xdd, 0xa0, 0x3c, + 0xc8, 0xe8, 0x0e, 0x5b, 0x08, 0x31, 0xdf, 0x0b, 0x20, 0xfe, 0x92, 0x76, 0x41, 0x5f, 0x4e, 0x9b, + 0x4c, 0x6c, 0x82, 0xfd, 0xcc, 0x4a, 0x72, 0x1e, 0xb8, 0x8d, 0x6e, 0xc1, 0xa3, 0xc8, 0x8f, 0xa9, + 0x6c, 0x56, 0x70, 0xc3, 0xa0, 0xc3, 0xf4, 0x6a, 0x4b, 0x5b, 0x2f, 0x3b, 0xaf, 0x0e, 0x07, 0xc6, + 0xad, 0x9d, 0xe9, 0x4b, 0x32, 0xeb, 0x8f, 0x2d, 0x54, 0x49, 0x44, 0x2f, 0x32, 0xbd, 0xdc, 0x2a, + 0xae, 0xd7, 0x9c, 0x35, 0xd1, 0xd1, 0x87, 0xd2, 0x72, 0x39, 0x30, 0xaa, 0x5f, 0x40, 0x5f, 0x1e, + 0x88, 0xf2, 0xc2, 0xef, 0xa2, 0x6a, 0xc2, 0x20, 0x0e, 0x44, 0x88, 0xe9, 0x1c, 0x64, 0xc5, 0x3f, + 0x54, 0x76, 0x92, 0x79, 0xe0, 0xdb, 0xa8, 0x98, 0xf8, 0x1d, 0x35, 0x07, 0x75, 0xe5, 0x58, 0x3c, + 0xdc, 0xfd, 0x8c, 0x08, 0x3b, 0x36, 0x51, 0xc5, 0x8b, 0xc3, 0x24, 0x62, 0x7a, 0x49, 0x8a, 0x23, + 0x21, 0xfe, 0xb9, 0xb4, 0x10, 0x75, 0x83, 0x03, 0x54, 0x86, 0x47, 0x3c, 0xa6, 0x7a, 0x45, 0x7e, + 0xbf, 0xdd, 0xe7, 0x5b, 0x79, 0xd6, 0x8e, 0xe0, 0xda, 0x09, 0x78, 0xdc, 0x1f, 0x7f, 0x4e, 0x69, + 0x23, 0xa9, 0x4c, 0x03, 0x10, 0x1a, 0xfb, 0xe0, 0x9b, 0xa8, 0x78, 0x02, 0xfd, 0x74, 0xf7, 0x10, + 0xf1, 0x13, 0x7f, 0x8a, 0xca, 0x3d, 0x7a, 0x9a, 0x80, 0x5a, 0xc1, 0xef, 0x2c, 0x8c, 0x47, 0xb2, + 0x7d, 0x2d, 0x20, 0x24, 0x45, 0x6e, 0x2f, 0x6d, 0x69, 0xe6, 0x9f, 0x1a, 0x32, 0x16, 0x2c, 0x4e, + 0xfc, 0x13, 0x42, 0xee, 0x68, 0x19, 0x31, 0x5d, 0x93, 0xf9, 0xb7, 0xaf, 0x9f, 0x7f, 0xb6, 0xd8, + 0xc6, 0x6f, 0x4c, 0x66, 0x62, 0x24, 0x27, 0x85, 0x37, 0x50, 0x3d, 0x47, 0x2d, 0x33, 0x5d, 0x71, + 0x6e, 0x0c, 0x07, 0x46, 0x3d, 0x47, 0x4e, 0xf2, 0x3e, 0xe6, 0x5f, 0x1a, 0xc2, 0xed, 0xd3, 0x84, + 0x71, 0x88, 0x0f, 0xe2, 0x84, 0x71, 0x27, 0x09, 0x3a, 0xa7, 0xf0, 0x02, 0x5e, 0xc4, 0x6f, 0x27, + 0x5e, 0xc4, 0xbb, 0x8b, 0xcb, 0x33, 0x13, 0xe4, 0xbc, 0xa7, 0xd0, 0x3c, 0xd7, 0xd0, 0xda, 0xac, + 0xfb, 0x0b, 0xd8, 0x59, 0xdf, 0x4c, 0xee, 0xac, 0x0f, 0xae, 0x91, 0xd4, 0x9c, 0x65, 0xf5, 0xf3, + 0x95, 0x29, 0xc9, 0x2d, 0xb5, 0x39, 0xb1, 0x7e, 0xd2, 0xd7, 0x36, 0x2b, 0xfd, 0x9c, 0x15, 0xf4, + 0x21, 0xaa, 0xf3, 0x31, 0x8d, 0x5a, 0x08, 0x2f, 0x2b, 0x50, 0x3d, 0xa7, 0x40, 0xf2, 0x7e, 0xe6, + 0x5d, 0x35, 0x63, 0x72, 0x2a, 0xb0, 0x31, 0xca, 0x56, 0x93, 0x4b, 0xa0, 0x36, 0x1d, 0xf4, 0x76, + 0xf5, 0xd7, 0xdf, 0x8c, 0xc2, 0xe3, 0xbf, 0x5b, 0x05, 0x67, 0xe7, 0xec, 0xa2, 0x59, 0x38, 0xbf, + 0x68, 0x16, 0x9e, 0x5c, 0x34, 0x0b, 0x8f, 0x87, 0x4d, 0xed, 0x6c, 0xd8, 0xd4, 0xce, 0x87, 0x4d, + 0xed, 0xc9, 0xb0, 0xa9, 0xfd, 0x33, 0x6c, 0x6a, 0xbf, 0x3c, 0x6d, 0x16, 0xbe, 0x33, 0x16, 0xfc, + 0xd1, 0xfd, 0x37, 0x00, 0x00, 0xff, 0xff, 0x17, 0xbe, 0xe3, 0x02, 0x0a, 0x0b, 0x00, 0x00, } func (m *CertificateSigningRequest) Marshal() (dAtA []byte, err error) { @@ -595,6 +687,129 @@ func (m *CertificateSigningRequestStatus) MarshalToSizedBuffer(dAtA []byte) (int return len(dAtA) - i, nil } +func (m *ClusterTrustBundle) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ClusterTrustBundle) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ClusterTrustBundle) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ClusterTrustBundleList) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ClusterTrustBundleList) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ClusterTrustBundleList) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Items) > 0 { + for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ClusterTrustBundleSpec) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ClusterTrustBundleSpec) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ClusterTrustBundleSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.TrustBundle) + copy(dAtA[i:], m.TrustBundle) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.TrustBundle))) + i-- + dAtA[i] = 0x12 + i -= len(m.SignerName) + copy(dAtA[i:], m.SignerName) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.SignerName))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m ExtraValue) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -755,6 +970,49 @@ func (m *CertificateSigningRequestStatus) Size() (n int) { return n } +func (m *ClusterTrustBundle) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Spec.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *ClusterTrustBundleList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ListMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Items) > 0 { + for _, e := range m.Items { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *ClusterTrustBundleSpec) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.SignerName) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.TrustBundle) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + func (m ExtraValue) Size() (n int) { if m == nil { return 0 @@ -862,6 +1120,44 @@ func (this *CertificateSigningRequestStatus) String() string { }, "") return s } +func (this *ClusterTrustBundle) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ClusterTrustBundle{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, + `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "ClusterTrustBundleSpec", "ClusterTrustBundleSpec", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *ClusterTrustBundleList) String() string { + if this == nil { + return "nil" + } + repeatedStringForItems := "[]ClusterTrustBundle{" + for _, f := range this.Items { + repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "ClusterTrustBundle", "ClusterTrustBundle", 1), `&`, ``, 1) + "," + } + repeatedStringForItems += "}" + s := strings.Join([]string{`&ClusterTrustBundleList{`, + `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, + `Items:` + repeatedStringForItems + `,`, + `}`, + }, "") + return s +} +func (this *ClusterTrustBundleSpec) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ClusterTrustBundleSpec{`, + `SignerName:` + fmt.Sprintf("%v", this.SignerName) + `,`, + `TrustBundle:` + fmt.Sprintf("%v", this.TrustBundle) + `,`, + `}`, + }, "") + return s +} func valueToStringGenerated(v interface{}) string { rv := reflect.ValueOf(v) if rv.IsNil() { @@ -1892,6 +2188,353 @@ func (m *CertificateSigningRequestStatus) Unmarshal(dAtA []byte) error { } return nil } +func (m *ClusterTrustBundle) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ClusterTrustBundle: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ClusterTrustBundle: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ClusterTrustBundleList) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ClusterTrustBundleList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ClusterTrustBundleList: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Items = append(m.Items, ClusterTrustBundle{}) + if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ClusterTrustBundleSpec) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ClusterTrustBundleSpec: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ClusterTrustBundleSpec: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SignerName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SignerName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TrustBundle", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TrustBundle = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *ExtraValue) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/go-controller/vendor/k8s.io/api/certificates/v1beta1/generated.proto b/go-controller/vendor/k8s.io/api/certificates/v1beta1/generated.proto index f3ec4c06e4..7c48270f65 100644 --- a/go-controller/vendor/k8s.io/api/certificates/v1beta1/generated.proto +++ b/go-controller/vendor/k8s.io/api/certificates/v1beta1/generated.proto @@ -190,6 +190,79 @@ message CertificateSigningRequestStatus { optional bytes certificate = 2; } +// ClusterTrustBundle is a cluster-scoped container for X.509 trust anchors +// (root certificates). +// +// ClusterTrustBundle objects are considered to be readable by any authenticated +// user in the cluster, because they can be mounted by pods using the +// `clusterTrustBundle` projection. All service accounts have read access to +// ClusterTrustBundles by default. Users who only have namespace-level access +// to a cluster can read ClusterTrustBundles by impersonating a serviceaccount +// that they have access to. +// +// It can be optionally associated with a particular assigner, in which case it +// contains one valid set of trust anchors for that signer. Signers may have +// multiple associated ClusterTrustBundles; each is an independent set of trust +// anchors for that signer. Admission control is used to enforce that only users +// with permissions on the signer can create or modify the corresponding bundle. +message ClusterTrustBundle { + // metadata contains the object metadata. + // +optional + optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; + + // spec contains the signer (if any) and trust anchors. + optional ClusterTrustBundleSpec spec = 2; +} + +// ClusterTrustBundleList is a collection of ClusterTrustBundle objects +message ClusterTrustBundleList { + // metadata contains the list metadata. + // + // +optional + optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; + + // items is a collection of ClusterTrustBundle objects + repeated ClusterTrustBundle items = 2; +} + +// ClusterTrustBundleSpec contains the signer and trust anchors. +message ClusterTrustBundleSpec { + // signerName indicates the associated signer, if any. + // + // In order to create or update a ClusterTrustBundle that sets signerName, + // you must have the following cluster-scoped permission: + // group=certificates.k8s.io resource=signers resourceName= + // verb=attest. + // + // If signerName is not empty, then the ClusterTrustBundle object must be + // named with the signer name as a prefix (translating slashes to colons). + // For example, for the signer name `example.com/foo`, valid + // ClusterTrustBundle object names include `example.com:foo:abc` and + // `example.com:foo:v1`. + // + // If signerName is empty, then the ClusterTrustBundle object's name must + // not have such a prefix. + // + // List/watch requests for ClusterTrustBundles can filter on this field + // using a `spec.signerName=NAME` field selector. + // + // +optional + optional string signerName = 1; + + // trustBundle contains the individual X.509 trust anchors for this + // bundle, as PEM bundle of PEM-wrapped, DER-formatted X.509 certificates. + // + // The data must consist only of PEM certificate blocks that parse as valid + // X.509 certificates. Each certificate must include a basic constraints + // extension with the CA bit set. The API server will reject objects that + // contain duplicate certificates, or that use PEM block headers. + // + // Users of ClusterTrustBundles, including Kubelet, are free to reorder and + // deduplicate certificate blocks in this file according to their own logic, + // as well as to drop PEM block headers and inter-block data. + optional string trustBundle = 2; +} + // ExtraValue masks the value so protobuf can generate // +protobuf.nullable=true // +protobuf.options.(gogoproto.goproto_stringer)=false diff --git a/go-controller/vendor/k8s.io/api/certificates/v1beta1/register.go b/go-controller/vendor/k8s.io/api/certificates/v1beta1/register.go index b4f3af9b9c..800dccd07d 100644 --- a/go-controller/vendor/k8s.io/api/certificates/v1beta1/register.go +++ b/go-controller/vendor/k8s.io/api/certificates/v1beta1/register.go @@ -51,6 +51,8 @@ func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, &CertificateSigningRequest{}, &CertificateSigningRequestList{}, + &ClusterTrustBundle{}, + &ClusterTrustBundleList{}, ) // Add the watch version that applies diff --git a/go-controller/vendor/k8s.io/api/certificates/v1beta1/types.go b/go-controller/vendor/k8s.io/api/certificates/v1beta1/types.go index 7e5a5c198a..1ce104807d 100644 --- a/go-controller/vendor/k8s.io/api/certificates/v1beta1/types.go +++ b/go-controller/vendor/k8s.io/api/certificates/v1beta1/types.go @@ -262,3 +262,88 @@ const ( UsageMicrosoftSGC KeyUsage = "microsoft sgc" UsageNetscapeSGC KeyUsage = "netscape sgc" ) + +// +genclient +// +genclient:nonNamespaced +// +k8s:prerelease-lifecycle-gen:introduced=1.33 +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ClusterTrustBundle is a cluster-scoped container for X.509 trust anchors +// (root certificates). +// +// ClusterTrustBundle objects are considered to be readable by any authenticated +// user in the cluster, because they can be mounted by pods using the +// `clusterTrustBundle` projection. All service accounts have read access to +// ClusterTrustBundles by default. Users who only have namespace-level access +// to a cluster can read ClusterTrustBundles by impersonating a serviceaccount +// that they have access to. +// +// It can be optionally associated with a particular assigner, in which case it +// contains one valid set of trust anchors for that signer. Signers may have +// multiple associated ClusterTrustBundles; each is an independent set of trust +// anchors for that signer. Admission control is used to enforce that only users +// with permissions on the signer can create or modify the corresponding bundle. +type ClusterTrustBundle struct { + metav1.TypeMeta `json:",inline"` + + // metadata contains the object metadata. + // +optional + metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // spec contains the signer (if any) and trust anchors. + Spec ClusterTrustBundleSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"` +} + +// ClusterTrustBundleSpec contains the signer and trust anchors. +type ClusterTrustBundleSpec struct { + // signerName indicates the associated signer, if any. + // + // In order to create or update a ClusterTrustBundle that sets signerName, + // you must have the following cluster-scoped permission: + // group=certificates.k8s.io resource=signers resourceName= + // verb=attest. + // + // If signerName is not empty, then the ClusterTrustBundle object must be + // named with the signer name as a prefix (translating slashes to colons). + // For example, for the signer name `example.com/foo`, valid + // ClusterTrustBundle object names include `example.com:foo:abc` and + // `example.com:foo:v1`. + // + // If signerName is empty, then the ClusterTrustBundle object's name must + // not have such a prefix. + // + // List/watch requests for ClusterTrustBundles can filter on this field + // using a `spec.signerName=NAME` field selector. + // + // +optional + SignerName string `json:"signerName,omitempty" protobuf:"bytes,1,opt,name=signerName"` + + // trustBundle contains the individual X.509 trust anchors for this + // bundle, as PEM bundle of PEM-wrapped, DER-formatted X.509 certificates. + // + // The data must consist only of PEM certificate blocks that parse as valid + // X.509 certificates. Each certificate must include a basic constraints + // extension with the CA bit set. The API server will reject objects that + // contain duplicate certificates, or that use PEM block headers. + // + // Users of ClusterTrustBundles, including Kubelet, are free to reorder and + // deduplicate certificate blocks in this file according to their own logic, + // as well as to drop PEM block headers and inter-block data. + TrustBundle string `json:"trustBundle" protobuf:"bytes,2,opt,name=trustBundle"` +} + +// +k8s:prerelease-lifecycle-gen:introduced=1.33 +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ClusterTrustBundleList is a collection of ClusterTrustBundle objects +type ClusterTrustBundleList struct { + metav1.TypeMeta `json:",inline"` + + // metadata contains the list metadata. + // + // +optional + metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // items is a collection of ClusterTrustBundle objects + Items []ClusterTrustBundle `json:"items" protobuf:"bytes,2,rep,name=items"` +} diff --git a/go-controller/vendor/k8s.io/api/certificates/v1beta1/types_swagger_doc_generated.go b/go-controller/vendor/k8s.io/api/certificates/v1beta1/types_swagger_doc_generated.go index f9ab1f13de..58c69e54d3 100644 --- a/go-controller/vendor/k8s.io/api/certificates/v1beta1/types_swagger_doc_generated.go +++ b/go-controller/vendor/k8s.io/api/certificates/v1beta1/types_swagger_doc_generated.go @@ -75,4 +75,34 @@ func (CertificateSigningRequestStatus) SwaggerDoc() map[string]string { return map_CertificateSigningRequestStatus } +var map_ClusterTrustBundle = map[string]string{ + "": "ClusterTrustBundle is a cluster-scoped container for X.509 trust anchors (root certificates).\n\nClusterTrustBundle objects are considered to be readable by any authenticated user in the cluster, because they can be mounted by pods using the `clusterTrustBundle` projection. All service accounts have read access to ClusterTrustBundles by default. Users who only have namespace-level access to a cluster can read ClusterTrustBundles by impersonating a serviceaccount that they have access to.\n\nIt can be optionally associated with a particular assigner, in which case it contains one valid set of trust anchors for that signer. Signers may have multiple associated ClusterTrustBundles; each is an independent set of trust anchors for that signer. Admission control is used to enforce that only users with permissions on the signer can create or modify the corresponding bundle.", + "metadata": "metadata contains the object metadata.", + "spec": "spec contains the signer (if any) and trust anchors.", +} + +func (ClusterTrustBundle) SwaggerDoc() map[string]string { + return map_ClusterTrustBundle +} + +var map_ClusterTrustBundleList = map[string]string{ + "": "ClusterTrustBundleList is a collection of ClusterTrustBundle objects", + "metadata": "metadata contains the list metadata.", + "items": "items is a collection of ClusterTrustBundle objects", +} + +func (ClusterTrustBundleList) SwaggerDoc() map[string]string { + return map_ClusterTrustBundleList +} + +var map_ClusterTrustBundleSpec = map[string]string{ + "": "ClusterTrustBundleSpec contains the signer and trust anchors.", + "signerName": "signerName indicates the associated signer, if any.\n\nIn order to create or update a ClusterTrustBundle that sets signerName, you must have the following cluster-scoped permission: group=certificates.k8s.io resource=signers resourceName= verb=attest.\n\nIf signerName is not empty, then the ClusterTrustBundle object must be named with the signer name as a prefix (translating slashes to colons). For example, for the signer name `example.com/foo`, valid ClusterTrustBundle object names include `example.com:foo:abc` and `example.com:foo:v1`.\n\nIf signerName is empty, then the ClusterTrustBundle object's name must not have such a prefix.\n\nList/watch requests for ClusterTrustBundles can filter on this field using a `spec.signerName=NAME` field selector.", + "trustBundle": "trustBundle contains the individual X.509 trust anchors for this bundle, as PEM bundle of PEM-wrapped, DER-formatted X.509 certificates.\n\nThe data must consist only of PEM certificate blocks that parse as valid X.509 certificates. Each certificate must include a basic constraints extension with the CA bit set. The API server will reject objects that contain duplicate certificates, or that use PEM block headers.\n\nUsers of ClusterTrustBundles, including Kubelet, are free to reorder and deduplicate certificate blocks in this file according to their own logic, as well as to drop PEM block headers and inter-block data.", +} + +func (ClusterTrustBundleSpec) SwaggerDoc() map[string]string { + return map_ClusterTrustBundleSpec +} + // AUTO-GENERATED FUNCTIONS END HERE diff --git a/go-controller/vendor/k8s.io/api/certificates/v1beta1/zz_generated.deepcopy.go b/go-controller/vendor/k8s.io/api/certificates/v1beta1/zz_generated.deepcopy.go index a315e2ac60..854e834739 100644 --- a/go-controller/vendor/k8s.io/api/certificates/v1beta1/zz_generated.deepcopy.go +++ b/go-controller/vendor/k8s.io/api/certificates/v1beta1/zz_generated.deepcopy.go @@ -188,6 +188,82 @@ func (in *CertificateSigningRequestStatus) DeepCopy() *CertificateSigningRequest return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterTrustBundle) DeepCopyInto(out *ClusterTrustBundle) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterTrustBundle. +func (in *ClusterTrustBundle) DeepCopy() *ClusterTrustBundle { + if in == nil { + return nil + } + out := new(ClusterTrustBundle) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterTrustBundle) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterTrustBundleList) DeepCopyInto(out *ClusterTrustBundleList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ClusterTrustBundle, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterTrustBundleList. +func (in *ClusterTrustBundleList) DeepCopy() *ClusterTrustBundleList { + if in == nil { + return nil + } + out := new(ClusterTrustBundleList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterTrustBundleList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterTrustBundleSpec) DeepCopyInto(out *ClusterTrustBundleSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterTrustBundleSpec. +func (in *ClusterTrustBundleSpec) DeepCopy() *ClusterTrustBundleSpec { + if in == nil { + return nil + } + out := new(ClusterTrustBundleSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in ExtraValue) DeepCopyInto(out *ExtraValue) { { diff --git a/go-controller/vendor/k8s.io/api/certificates/v1beta1/zz_generated.prerelease-lifecycle.go b/go-controller/vendor/k8s.io/api/certificates/v1beta1/zz_generated.prerelease-lifecycle.go index 480a329361..062b46f164 100644 --- a/go-controller/vendor/k8s.io/api/certificates/v1beta1/zz_generated.prerelease-lifecycle.go +++ b/go-controller/vendor/k8s.io/api/certificates/v1beta1/zz_generated.prerelease-lifecycle.go @@ -72,3 +72,39 @@ func (in *CertificateSigningRequestList) APILifecycleReplacement() schema.GroupV func (in *CertificateSigningRequestList) APILifecycleRemoved() (major, minor int) { return 1, 22 } + +// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. +func (in *ClusterTrustBundle) APILifecycleIntroduced() (major, minor int) { + return 1, 33 +} + +// APILifecycleDeprecated is an autogenerated function, returning the release in which the API struct was or will be deprecated as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:deprecated" tags in types.go or "k8s:prerelease-lifecycle-gen:introduced" plus three minor. +func (in *ClusterTrustBundle) APILifecycleDeprecated() (major, minor int) { + return 1, 36 +} + +// APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. +func (in *ClusterTrustBundle) APILifecycleRemoved() (major, minor int) { + return 1, 39 +} + +// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. +func (in *ClusterTrustBundleList) APILifecycleIntroduced() (major, minor int) { + return 1, 33 +} + +// APILifecycleDeprecated is an autogenerated function, returning the release in which the API struct was or will be deprecated as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:deprecated" tags in types.go or "k8s:prerelease-lifecycle-gen:introduced" plus three minor. +func (in *ClusterTrustBundleList) APILifecycleDeprecated() (major, minor int) { + return 1, 36 +} + +// APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. +func (in *ClusterTrustBundleList) APILifecycleRemoved() (major, minor int) { + return 1, 39 +} diff --git a/go-controller/vendor/k8s.io/api/coordination/v1/doc.go b/go-controller/vendor/k8s.io/api/coordination/v1/doc.go index 9b2fbbda3a..82ae6340c7 100644 --- a/go-controller/vendor/k8s.io/api/coordination/v1/doc.go +++ b/go-controller/vendor/k8s.io/api/coordination/v1/doc.go @@ -21,4 +21,4 @@ limitations under the License. // +groupName=coordination.k8s.io -package v1 // import "k8s.io/api/coordination/v1" +package v1 diff --git a/go-controller/vendor/k8s.io/api/coordination/v1alpha2/doc.go b/go-controller/vendor/k8s.io/api/coordination/v1alpha2/doc.go index 5e6d655302..dff7df47fc 100644 --- a/go-controller/vendor/k8s.io/api/coordination/v1alpha2/doc.go +++ b/go-controller/vendor/k8s.io/api/coordination/v1alpha2/doc.go @@ -21,4 +21,4 @@ limitations under the License. // +groupName=coordination.k8s.io -package v1alpha2 // import "k8s.io/api/coordination/v1alpha2" +package v1alpha2 diff --git a/go-controller/vendor/k8s.io/api/coordination/v1alpha2/generated.proto b/go-controller/vendor/k8s.io/api/coordination/v1alpha2/generated.proto index 7e56cd7f96..250c6113ec 100644 --- a/go-controller/vendor/k8s.io/api/coordination/v1alpha2/generated.proto +++ b/go-controller/vendor/k8s.io/api/coordination/v1alpha2/generated.proto @@ -92,8 +92,6 @@ message LeaseCandidateSpec { // If multiple candidates for the same Lease return different strategies, the strategy provided // by the candidate with the latest BinaryVersion will be used. If there is still conflict, // this is a user error and coordinated leader election will not operate the Lease until resolved. - // (Alpha) Using this field requires the CoordinatedLeaderElection feature gate to be enabled. - // +featureGate=CoordinatedLeaderElection // +required optional string strategy = 6; } diff --git a/go-controller/vendor/k8s.io/api/coordination/v1alpha2/types.go b/go-controller/vendor/k8s.io/api/coordination/v1alpha2/types.go index 2f53b097a2..13e1deb067 100644 --- a/go-controller/vendor/k8s.io/api/coordination/v1alpha2/types.go +++ b/go-controller/vendor/k8s.io/api/coordination/v1alpha2/types.go @@ -73,8 +73,6 @@ type LeaseCandidateSpec struct { // If multiple candidates for the same Lease return different strategies, the strategy provided // by the candidate with the latest BinaryVersion will be used. If there is still conflict, // this is a user error and coordinated leader election will not operate the Lease until resolved. - // (Alpha) Using this field requires the CoordinatedLeaderElection feature gate to be enabled. - // +featureGate=CoordinatedLeaderElection // +required Strategy v1.CoordinatedLeaseStrategy `json:"strategy,omitempty" protobuf:"bytes,6,opt,name=strategy"` } diff --git a/go-controller/vendor/k8s.io/api/coordination/v1alpha2/types_swagger_doc_generated.go b/go-controller/vendor/k8s.io/api/coordination/v1alpha2/types_swagger_doc_generated.go index 39534e6adb..f7e29849e4 100644 --- a/go-controller/vendor/k8s.io/api/coordination/v1alpha2/types_swagger_doc_generated.go +++ b/go-controller/vendor/k8s.io/api/coordination/v1alpha2/types_swagger_doc_generated.go @@ -54,7 +54,7 @@ var map_LeaseCandidateSpec = map[string]string{ "renewTime": "RenewTime is the time that the LeaseCandidate was last updated. Any time a Lease needs to do leader election, the PingTime field is updated to signal to the LeaseCandidate that they should update the RenewTime. Old LeaseCandidate objects are also garbage collected if it has been hours since the last renew. The PingTime field is updated regularly to prevent garbage collection for still active LeaseCandidates.", "binaryVersion": "BinaryVersion is the binary version. It must be in a semver format without leading `v`. This field is required.", "emulationVersion": "EmulationVersion is the emulation version. It must be in a semver format without leading `v`. EmulationVersion must be less than or equal to BinaryVersion. This field is required when strategy is \"OldestEmulationVersion\"", - "strategy": "Strategy is the strategy that coordinated leader election will use for picking the leader. If multiple candidates for the same Lease return different strategies, the strategy provided by the candidate with the latest BinaryVersion will be used. If there is still conflict, this is a user error and coordinated leader election will not operate the Lease until resolved. (Alpha) Using this field requires the CoordinatedLeaderElection feature gate to be enabled.", + "strategy": "Strategy is the strategy that coordinated leader election will use for picking the leader. If multiple candidates for the same Lease return different strategies, the strategy provided by the candidate with the latest BinaryVersion will be used. If there is still conflict, this is a user error and coordinated leader election will not operate the Lease until resolved.", } func (LeaseCandidateSpec) SwaggerDoc() map[string]string { diff --git a/go-controller/vendor/k8s.io/api/coordination/v1beta1/doc.go b/go-controller/vendor/k8s.io/api/coordination/v1beta1/doc.go index e733411aa9..cab8becf67 100644 --- a/go-controller/vendor/k8s.io/api/coordination/v1beta1/doc.go +++ b/go-controller/vendor/k8s.io/api/coordination/v1beta1/doc.go @@ -21,4 +21,4 @@ limitations under the License. // +groupName=coordination.k8s.io -package v1beta1 // import "k8s.io/api/coordination/v1beta1" +package v1beta1 diff --git a/go-controller/vendor/k8s.io/api/coordination/v1beta1/generated.pb.go b/go-controller/vendor/k8s.io/api/coordination/v1beta1/generated.pb.go index bea9b8146a..52fd4167fa 100644 --- a/go-controller/vendor/k8s.io/api/coordination/v1beta1/generated.pb.go +++ b/go-controller/vendor/k8s.io/api/coordination/v1beta1/generated.pb.go @@ -74,10 +74,94 @@ func (m *Lease) XXX_DiscardUnknown() { var xxx_messageInfo_Lease proto.InternalMessageInfo +func (m *LeaseCandidate) Reset() { *m = LeaseCandidate{} } +func (*LeaseCandidate) ProtoMessage() {} +func (*LeaseCandidate) Descriptor() ([]byte, []int) { + return fileDescriptor_8d4e223b8bb23da3, []int{1} +} +func (m *LeaseCandidate) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *LeaseCandidate) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *LeaseCandidate) XXX_Merge(src proto.Message) { + xxx_messageInfo_LeaseCandidate.Merge(m, src) +} +func (m *LeaseCandidate) XXX_Size() int { + return m.Size() +} +func (m *LeaseCandidate) XXX_DiscardUnknown() { + xxx_messageInfo_LeaseCandidate.DiscardUnknown(m) +} + +var xxx_messageInfo_LeaseCandidate proto.InternalMessageInfo + +func (m *LeaseCandidateList) Reset() { *m = LeaseCandidateList{} } +func (*LeaseCandidateList) ProtoMessage() {} +func (*LeaseCandidateList) Descriptor() ([]byte, []int) { + return fileDescriptor_8d4e223b8bb23da3, []int{2} +} +func (m *LeaseCandidateList) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *LeaseCandidateList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *LeaseCandidateList) XXX_Merge(src proto.Message) { + xxx_messageInfo_LeaseCandidateList.Merge(m, src) +} +func (m *LeaseCandidateList) XXX_Size() int { + return m.Size() +} +func (m *LeaseCandidateList) XXX_DiscardUnknown() { + xxx_messageInfo_LeaseCandidateList.DiscardUnknown(m) +} + +var xxx_messageInfo_LeaseCandidateList proto.InternalMessageInfo + +func (m *LeaseCandidateSpec) Reset() { *m = LeaseCandidateSpec{} } +func (*LeaseCandidateSpec) ProtoMessage() {} +func (*LeaseCandidateSpec) Descriptor() ([]byte, []int) { + return fileDescriptor_8d4e223b8bb23da3, []int{3} +} +func (m *LeaseCandidateSpec) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *LeaseCandidateSpec) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *LeaseCandidateSpec) XXX_Merge(src proto.Message) { + xxx_messageInfo_LeaseCandidateSpec.Merge(m, src) +} +func (m *LeaseCandidateSpec) XXX_Size() int { + return m.Size() +} +func (m *LeaseCandidateSpec) XXX_DiscardUnknown() { + xxx_messageInfo_LeaseCandidateSpec.DiscardUnknown(m) +} + +var xxx_messageInfo_LeaseCandidateSpec proto.InternalMessageInfo + func (m *LeaseList) Reset() { *m = LeaseList{} } func (*LeaseList) ProtoMessage() {} func (*LeaseList) Descriptor() ([]byte, []int) { - return fileDescriptor_8d4e223b8bb23da3, []int{1} + return fileDescriptor_8d4e223b8bb23da3, []int{4} } func (m *LeaseList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -105,7 +189,7 @@ var xxx_messageInfo_LeaseList proto.InternalMessageInfo func (m *LeaseSpec) Reset() { *m = LeaseSpec{} } func (*LeaseSpec) ProtoMessage() {} func (*LeaseSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_8d4e223b8bb23da3, []int{2} + return fileDescriptor_8d4e223b8bb23da3, []int{5} } func (m *LeaseSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -132,6 +216,9 @@ var xxx_messageInfo_LeaseSpec proto.InternalMessageInfo func init() { proto.RegisterType((*Lease)(nil), "k8s.io.api.coordination.v1beta1.Lease") + proto.RegisterType((*LeaseCandidate)(nil), "k8s.io.api.coordination.v1beta1.LeaseCandidate") + proto.RegisterType((*LeaseCandidateList)(nil), "k8s.io.api.coordination.v1beta1.LeaseCandidateList") + proto.RegisterType((*LeaseCandidateSpec)(nil), "k8s.io.api.coordination.v1beta1.LeaseCandidateSpec") proto.RegisterType((*LeaseList)(nil), "k8s.io.api.coordination.v1beta1.LeaseList") proto.RegisterType((*LeaseSpec)(nil), "k8s.io.api.coordination.v1beta1.LeaseSpec") } @@ -141,45 +228,54 @@ func init() { } var fileDescriptor_8d4e223b8bb23da3 = []byte{ - // 600 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x94, 0xdf, 0x4e, 0xd4, 0x4e, - 0x14, 0xc7, 0xb7, 0xb0, 0xfb, 0xfb, 0xb1, 0xb3, 0xf2, 0x27, 0x23, 0x17, 0x0d, 0x17, 0x2d, 0xe1, - 0xc2, 0x10, 0x12, 0xa7, 0x82, 0xc6, 0x18, 0x13, 0x13, 0x2d, 0x9a, 0x48, 0x2c, 0xd1, 0x14, 0xae, - 0x0c, 0x89, 0xce, 0xb6, 0x87, 0xee, 0x08, 0xed, 0xd4, 0x99, 0x59, 0x0c, 0x77, 0x3e, 0x82, 0x4f, - 0xa3, 0xf1, 0x0d, 0xb8, 0xe4, 0x92, 0xab, 0x46, 0xc6, 0xb7, 0xf0, 0xca, 0xcc, 0x6c, 0x61, 0x61, - 0x81, 0xb0, 0xf1, 0x6e, 0xe7, 0x9c, 0xf3, 0xfd, 0x9c, 0xef, 0x9c, 0xb3, 0x53, 0x14, 0xec, 0x3d, - 0x91, 0x84, 0xf1, 0x80, 0x96, 0x2c, 0x48, 0x38, 0x17, 0x29, 0x2b, 0xa8, 0x62, 0xbc, 0x08, 0x0e, - 0x56, 0xbb, 0xa0, 0xe8, 0x6a, 0x90, 0x41, 0x01, 0x82, 0x2a, 0x48, 0x49, 0x29, 0xb8, 0xe2, 0xd8, - 0x1f, 0x08, 0x08, 0x2d, 0x19, 0xb9, 0x28, 0x20, 0xb5, 0x60, 0xe1, 0x7e, 0xc6, 0x54, 0xaf, 0xdf, - 0x25, 0x09, 0xcf, 0x83, 0x8c, 0x67, 0x3c, 0xb0, 0xba, 0x6e, 0x7f, 0xd7, 0x9e, 0xec, 0xc1, 0xfe, - 0x1a, 0xf0, 0x16, 0x56, 0x6e, 0x36, 0x30, 0xda, 0x7b, 0xe1, 0xd1, 0xb0, 0x36, 0xa7, 0x49, 0x8f, - 0x15, 0x20, 0x0e, 0x83, 0x72, 0x2f, 0x33, 0x01, 0x19, 0xe4, 0xa0, 0xe8, 0x75, 0xaa, 0xe0, 0x26, - 0x95, 0xe8, 0x17, 0x8a, 0xe5, 0x70, 0x45, 0xf0, 0xf8, 0x36, 0x81, 0x4c, 0x7a, 0x90, 0xd3, 0x51, - 0xdd, 0xd2, 0x0f, 0x07, 0xb5, 0x22, 0xa0, 0x12, 0xf0, 0x47, 0x34, 0x65, 0xdc, 0xa4, 0x54, 0x51, - 0xd7, 0x59, 0x74, 0x96, 0x3b, 0x6b, 0x0f, 0xc8, 0x70, 0x6e, 0xe7, 0x50, 0x52, 0xee, 0x65, 0x26, - 0x20, 0x89, 0xa9, 0x26, 0x07, 0xab, 0xe4, 0x6d, 0xf7, 0x13, 0x24, 0x6a, 0x13, 0x14, 0x0d, 0xf1, - 0x51, 0xe5, 0x37, 0x74, 0xe5, 0xa3, 0x61, 0x2c, 0x3e, 0xa7, 0xe2, 0x08, 0x35, 0x65, 0x09, 0x89, - 0x3b, 0x61, 0xe9, 0x2b, 0xe4, 0x96, 0xad, 0x10, 0xeb, 0x6b, 0xab, 0x84, 0x24, 0xbc, 0x53, 0x73, - 0x9b, 0xe6, 0x14, 0x5b, 0xca, 0xd2, 0x77, 0x07, 0xb5, 0x6d, 0x45, 0xc4, 0xa4, 0xc2, 0x3b, 0x57, - 0xdc, 0x93, 0xf1, 0xdc, 0x1b, 0xb5, 0xf5, 0x3e, 0x57, 0xf7, 0x98, 0x3a, 0x8b, 0x5c, 0x70, 0xfe, - 0x06, 0xb5, 0x98, 0x82, 0x5c, 0xba, 0x13, 0x8b, 0x93, 0xcb, 0x9d, 0xb5, 0x7b, 0xe3, 0x59, 0x0f, - 0xa7, 0x6b, 0x64, 0x6b, 0xc3, 0x88, 0xe3, 0x01, 0x63, 0xe9, 0x67, 0xb3, 0x36, 0x6e, 0x2e, 0x83, - 0x9f, 0xa2, 0x99, 0x1e, 0xdf, 0x4f, 0x41, 0x6c, 0xa4, 0x50, 0x28, 0xa6, 0x0e, 0xad, 0xfd, 0x76, - 0x88, 0x75, 0xe5, 0xcf, 0xbc, 0xbe, 0x94, 0x89, 0x47, 0x2a, 0x71, 0x84, 0xe6, 0xf7, 0x0d, 0xe8, - 0x65, 0x5f, 0xd8, 0xf6, 0x5b, 0x90, 0xf0, 0x22, 0x95, 0x76, 0xc0, 0xad, 0xd0, 0xd5, 0x95, 0x3f, - 0x1f, 0x5d, 0x93, 0x8f, 0xaf, 0x55, 0xe1, 0x2e, 0xea, 0xd0, 0xe4, 0x73, 0x9f, 0x09, 0xd8, 0x66, - 0x39, 0xb8, 0x93, 0x76, 0x8a, 0xc1, 0x78, 0x53, 0xdc, 0x64, 0x89, 0xe0, 0x46, 0x16, 0xce, 0xea, - 0xca, 0xef, 0xbc, 0x18, 0x72, 0xe2, 0x8b, 0x50, 0xbc, 0x83, 0xda, 0x02, 0x0a, 0xf8, 0x62, 0x3b, - 0x34, 0xff, 0xad, 0xc3, 0xb4, 0xae, 0xfc, 0x76, 0x7c, 0x46, 0x89, 0x87, 0x40, 0xfc, 0x1c, 0xcd, - 0xd9, 0x9b, 0x6d, 0x0b, 0x5a, 0x48, 0x66, 0xee, 0x26, 0xdd, 0x96, 0x9d, 0xc5, 0xbc, 0xae, 0xfc, - 0xb9, 0x68, 0x24, 0x17, 0x5f, 0xa9, 0xc6, 0x1f, 0xd0, 0x94, 0x54, 0xe6, 0x7d, 0x64, 0x87, 0xee, - 0x7f, 0x76, 0x0f, 0xeb, 0xe6, 0x2f, 0xb1, 0x55, 0xc7, 0xfe, 0x54, 0xfe, 0xc3, 0x9b, 0xdf, 0x3e, - 0x59, 0x3f, 0x3b, 0x43, 0x3a, 0x58, 0x70, 0x2d, 0x8b, 0xcf, 0xa1, 0xf8, 0x19, 0x9a, 0x2d, 0x05, - 0xec, 0x82, 0x10, 0x90, 0x0e, 0xb6, 0xeb, 0xfe, 0x6f, 0xfb, 0xdc, 0xd5, 0x95, 0x3f, 0xfb, 0xee, - 0x72, 0x2a, 0x1e, 0xad, 0x0d, 0x5f, 0x1d, 0x9d, 0x7a, 0x8d, 0xe3, 0x53, 0xaf, 0x71, 0x72, 0xea, - 0x35, 0xbe, 0x6a, 0xcf, 0x39, 0xd2, 0x9e, 0x73, 0xac, 0x3d, 0xe7, 0x44, 0x7b, 0xce, 0x2f, 0xed, - 0x39, 0xdf, 0x7e, 0x7b, 0x8d, 0xf7, 0xfe, 0x2d, 0x1f, 0xc8, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, - 0x57, 0x93, 0xf3, 0xef, 0x42, 0x05, 0x00, 0x00, + // 750 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0xdd, 0x4e, 0x1b, 0x39, + 0x18, 0xcd, 0x40, 0xb2, 0x9b, 0x38, 0x04, 0xb2, 0x5e, 0x56, 0x1a, 0x71, 0x31, 0x83, 0x72, 0xb1, + 0x42, 0x48, 0xeb, 0x59, 0x60, 0xb5, 0x5a, 0x6d, 0x55, 0xa9, 0x1d, 0x40, 0x2d, 0x6a, 0x68, 0x91, + 0xa1, 0x95, 0x5a, 0x21, 0xb5, 0xce, 0x8c, 0x99, 0xb8, 0x30, 0x3f, 0xf5, 0x38, 0x54, 0xb9, 0xeb, + 0x23, 0xf4, 0x69, 0x5a, 0xf5, 0x0d, 0xd2, 0x3b, 0x2e, 0xb9, 0x8a, 0xca, 0x54, 0xea, 0x43, 0xf4, + 0xaa, 0xb2, 0x33, 0xf9, 0x27, 0x22, 0x6d, 0x11, 0x77, 0xf1, 0xf7, 0x9d, 0x73, 0xfc, 0x1d, 0xfb, + 0x38, 0x1a, 0x60, 0x1d, 0xff, 0x17, 0x23, 0x16, 0x5a, 0x24, 0x62, 0x96, 0x13, 0x86, 0xdc, 0x65, + 0x01, 0x11, 0x2c, 0x0c, 0xac, 0xd3, 0xb5, 0x1a, 0x15, 0x64, 0xcd, 0xf2, 0x68, 0x40, 0x39, 0x11, + 0xd4, 0x45, 0x11, 0x0f, 0x45, 0x08, 0xcd, 0x0e, 0x01, 0x91, 0x88, 0xa1, 0x41, 0x02, 0x4a, 0x09, + 0x4b, 0x7f, 0x79, 0x4c, 0xd4, 0x1b, 0x35, 0xe4, 0x84, 0xbe, 0xe5, 0x85, 0x5e, 0x68, 0x29, 0x5e, + 0xad, 0x71, 0xa4, 0x56, 0x6a, 0xa1, 0x7e, 0x75, 0xf4, 0x96, 0x56, 0x27, 0x0f, 0x30, 0xba, 0xf7, + 0xd2, 0x3f, 0x7d, 0xac, 0x4f, 0x9c, 0x3a, 0x0b, 0x28, 0x6f, 0x5a, 0xd1, 0xb1, 0x27, 0x0b, 0xb1, + 0xe5, 0x53, 0x41, 0x2e, 0x63, 0x59, 0x93, 0x58, 0xbc, 0x11, 0x08, 0xe6, 0xd3, 0x31, 0xc2, 0xbf, + 0x57, 0x11, 0x62, 0xa7, 0x4e, 0x7d, 0x32, 0xca, 0xab, 0xbc, 0xd7, 0x40, 0xae, 0x4a, 0x49, 0x4c, + 0xe1, 0x0b, 0x90, 0x97, 0xd3, 0xb8, 0x44, 0x10, 0x5d, 0x5b, 0xd6, 0x56, 0x8a, 0xeb, 0x7f, 0xa3, + 0xfe, 0xb9, 0xf5, 0x44, 0x51, 0x74, 0xec, 0xc9, 0x42, 0x8c, 0x24, 0x1a, 0x9d, 0xae, 0xa1, 0x47, + 0xb5, 0x97, 0xd4, 0x11, 0xbb, 0x54, 0x10, 0x1b, 0xb6, 0xda, 0x66, 0x26, 0x69, 0x9b, 0xa0, 0x5f, + 0xc3, 0x3d, 0x55, 0x58, 0x05, 0xd9, 0x38, 0xa2, 0x8e, 0x3e, 0xa3, 0xd4, 0x57, 0xd1, 0x15, 0xb7, + 0x82, 0xd4, 0x5c, 0xfb, 0x11, 0x75, 0xec, 0xb9, 0x54, 0x37, 0x2b, 0x57, 0x58, 0xa9, 0x54, 0x3e, + 0x6a, 0x60, 0x5e, 0x21, 0x36, 0x49, 0xe0, 0x32, 0x97, 0x88, 0x9b, 0xb0, 0xf0, 0x78, 0xc8, 0xc2, + 0xc6, 0x74, 0x16, 0x7a, 0x03, 0x4e, 0xf4, 0xd2, 0xd2, 0x00, 0x1c, 0x86, 0x56, 0x59, 0x2c, 0xe0, + 0xe1, 0x98, 0x1f, 0x34, 0x9d, 0x1f, 0xc9, 0x56, 0x6e, 0xca, 0xe9, 0x66, 0xf9, 0x6e, 0x65, 0xc0, + 0xcb, 0x01, 0xc8, 0x31, 0x41, 0xfd, 0x58, 0x9f, 0x59, 0x9e, 0x5d, 0x29, 0xae, 0x5b, 0xdf, 0x69, + 0xc6, 0x2e, 0xa5, 0xda, 0xb9, 0x1d, 0xa9, 0x82, 0x3b, 0x62, 0x95, 0x2f, 0xb3, 0xa3, 0x56, 0xa4, + 0x4f, 0x68, 0x81, 0xc2, 0x89, 0xac, 0x3e, 0x24, 0x3e, 0x55, 0x5e, 0x0a, 0xf6, 0x6f, 0x29, 0xbf, + 0x50, 0xed, 0x36, 0x70, 0x1f, 0x03, 0x9f, 0x82, 0x7c, 0xc4, 0x02, 0xef, 0x80, 0xf9, 0x34, 0x3d, + 0x6d, 0x6b, 0x3a, 0xef, 0xbb, 0xcc, 0xe1, 0xa1, 0xa4, 0xd9, 0x73, 0xd2, 0xf8, 0x5e, 0x2a, 0x82, + 0x7b, 0x72, 0xf0, 0x10, 0x14, 0x38, 0x0d, 0xe8, 0x6b, 0xa5, 0x3d, 0xfb, 0x63, 0xda, 0x25, 0x39, + 0x38, 0xee, 0xaa, 0xe0, 0xbe, 0x20, 0xbc, 0x05, 0x4a, 0x35, 0x16, 0x10, 0xde, 0x7c, 0x42, 0x79, + 0xcc, 0xc2, 0x40, 0xcf, 0x2a, 0xb7, 0x7f, 0xa4, 0x6e, 0x4b, 0xf6, 0x60, 0x13, 0x0f, 0x63, 0xe1, + 0x16, 0x28, 0x53, 0xbf, 0x71, 0xa2, 0xce, 0xbd, 0xcb, 0xcf, 0x29, 0xbe, 0x9e, 0xf2, 0xcb, 0xdb, + 0x23, 0x7d, 0x3c, 0xc6, 0x80, 0x0e, 0xc8, 0xc7, 0x42, 0xbe, 0x72, 0xaf, 0xa9, 0xff, 0xa2, 0xd8, + 0xf7, 0xba, 0x39, 0xd8, 0x4f, 0xeb, 0x5f, 0xdb, 0xe6, 0xc6, 0xe4, 0x7f, 0x31, 0xb4, 0xd9, 0x5d, + 0x53, 0xb7, 0xf3, 0x0a, 0x53, 0x1a, 0xee, 0x09, 0x57, 0xde, 0x69, 0xa0, 0x73, 0x73, 0x37, 0x10, + 0xd5, 0x07, 0xc3, 0x51, 0xfd, 0x73, 0xba, 0xa8, 0x4e, 0x48, 0xe8, 0x87, 0x6c, 0x3a, 0xb8, 0x0a, + 0xe6, 0xff, 0x60, 0xbe, 0x1e, 0x9e, 0xb8, 0x94, 0xef, 0xb8, 0x34, 0x10, 0x4c, 0x34, 0xd3, 0x74, + 0xc2, 0xa4, 0x6d, 0xce, 0xdf, 0x1f, 0xea, 0xe0, 0x11, 0x24, 0xac, 0x82, 0x45, 0x15, 0xd8, 0xad, + 0x06, 0x57, 0xdb, 0xef, 0x53, 0x27, 0x0c, 0xdc, 0x58, 0xe5, 0x35, 0x67, 0xeb, 0x49, 0xdb, 0x5c, + 0xac, 0x5e, 0xd2, 0xc7, 0x97, 0xb2, 0x60, 0x0d, 0x14, 0x89, 0xf3, 0xaa, 0xc1, 0x38, 0xfd, 0x99, + 0x60, 0x2e, 0x24, 0x6d, 0xb3, 0x78, 0xb7, 0xaf, 0x83, 0x07, 0x45, 0x87, 0xa3, 0x9f, 0xbd, 0xee, + 0xe8, 0xdf, 0x01, 0x65, 0xe5, 0xec, 0x80, 0x93, 0x20, 0x66, 0xd2, 0x5b, 0xac, 0xd2, 0x9b, 0xb3, + 0x17, 0x65, 0x72, 0xab, 0x23, 0x3d, 0x3c, 0x86, 0x86, 0xcf, 0xc7, 0x92, 0xbb, 0x79, 0xad, 0xa9, + 0x85, 0xb7, 0xc1, 0x42, 0xc4, 0xe9, 0x11, 0xe5, 0x9c, 0xba, 0x9d, 0xdb, 0xd5, 0x7f, 0x55, 0xfb, + 0xfc, 0x9e, 0xb4, 0xcd, 0x85, 0xbd, 0xe1, 0x16, 0x1e, 0xc5, 0xda, 0xdb, 0xad, 0x0b, 0x23, 0x73, + 0x76, 0x61, 0x64, 0xce, 0x2f, 0x8c, 0xcc, 0x9b, 0xc4, 0xd0, 0x5a, 0x89, 0xa1, 0x9d, 0x25, 0x86, + 0x76, 0x9e, 0x18, 0xda, 0xa7, 0xc4, 0xd0, 0xde, 0x7e, 0x36, 0x32, 0xcf, 0xcc, 0x2b, 0x3e, 0x50, + 0xbe, 0x05, 0x00, 0x00, 0xff, 0xff, 0xff, 0x56, 0x51, 0x57, 0xc2, 0x08, 0x00, 0x00, } func (m *Lease) Marshal() (dAtA []byte, err error) { @@ -225,6 +321,163 @@ func (m *Lease) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *LeaseCandidate) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *LeaseCandidate) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *LeaseCandidate) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *LeaseCandidateList) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *LeaseCandidateList) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *LeaseCandidateList) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Items) > 0 { + for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *LeaseCandidateSpec) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *LeaseCandidateSpec) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *LeaseCandidateSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Strategy) + copy(dAtA[i:], m.Strategy) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Strategy))) + i-- + dAtA[i] = 0x32 + i -= len(m.EmulationVersion) + copy(dAtA[i:], m.EmulationVersion) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.EmulationVersion))) + i-- + dAtA[i] = 0x2a + i -= len(m.BinaryVersion) + copy(dAtA[i:], m.BinaryVersion) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.BinaryVersion))) + i-- + dAtA[i] = 0x22 + if m.RenewTime != nil { + { + size, err := m.RenewTime.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if m.PingTime != nil { + { + size, err := m.PingTime.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + i -= len(m.LeaseName) + copy(dAtA[i:], m.LeaseName) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.LeaseName))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *LeaseList) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -374,6 +627,61 @@ func (m *Lease) Size() (n int) { return n } +func (m *LeaseCandidate) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Spec.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *LeaseCandidateList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ListMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Items) > 0 { + for _, e := range m.Items { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *LeaseCandidateSpec) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.LeaseName) + n += 1 + l + sovGenerated(uint64(l)) + if m.PingTime != nil { + l = m.PingTime.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if m.RenewTime != nil { + l = m.RenewTime.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + l = len(m.BinaryVersion) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.EmulationVersion) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Strategy) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + func (m *LeaseList) Size() (n int) { if m == nil { return 0 @@ -443,6 +751,48 @@ func (this *Lease) String() string { }, "") return s } +func (this *LeaseCandidate) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&LeaseCandidate{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, + `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "LeaseCandidateSpec", "LeaseCandidateSpec", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *LeaseCandidateList) String() string { + if this == nil { + return "nil" + } + repeatedStringForItems := "[]LeaseCandidate{" + for _, f := range this.Items { + repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "LeaseCandidate", "LeaseCandidate", 1), `&`, ``, 1) + "," + } + repeatedStringForItems += "}" + s := strings.Join([]string{`&LeaseCandidateList{`, + `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, + `Items:` + repeatedStringForItems + `,`, + `}`, + }, "") + return s +} +func (this *LeaseCandidateSpec) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&LeaseCandidateSpec{`, + `LeaseName:` + fmt.Sprintf("%v", this.LeaseName) + `,`, + `PingTime:` + strings.Replace(fmt.Sprintf("%v", this.PingTime), "MicroTime", "v1.MicroTime", 1) + `,`, + `RenewTime:` + strings.Replace(fmt.Sprintf("%v", this.RenewTime), "MicroTime", "v1.MicroTime", 1) + `,`, + `BinaryVersion:` + fmt.Sprintf("%v", this.BinaryVersion) + `,`, + `EmulationVersion:` + fmt.Sprintf("%v", this.EmulationVersion) + `,`, + `Strategy:` + fmt.Sprintf("%v", this.Strategy) + `,`, + `}`, + }, "") + return s +} func (this *LeaseList) String() string { if this == nil { return "nil" @@ -599,6 +949,489 @@ func (m *Lease) Unmarshal(dAtA []byte) error { } return nil } +func (m *LeaseCandidate) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: LeaseCandidate: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LeaseCandidate: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *LeaseCandidateList) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: LeaseCandidateList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LeaseCandidateList: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Items = append(m.Items, LeaseCandidate{}) + if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *LeaseCandidateSpec) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: LeaseCandidateSpec: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LeaseCandidateSpec: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field LeaseName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.LeaseName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PingTime", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.PingTime == nil { + m.PingTime = &v1.MicroTime{} + } + if err := m.PingTime.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RenewTime", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.RenewTime == nil { + m.RenewTime = &v1.MicroTime{} + } + if err := m.RenewTime.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BinaryVersion", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BinaryVersion = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field EmulationVersion", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.EmulationVersion = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Strategy", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Strategy = k8s_io_api_coordination_v1.CoordinatedLeaseStrategy(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *LeaseList) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/go-controller/vendor/k8s.io/api/coordination/v1beta1/generated.proto b/go-controller/vendor/k8s.io/api/coordination/v1beta1/generated.proto index 088811a74b..7ca043f528 100644 --- a/go-controller/vendor/k8s.io/api/coordination/v1beta1/generated.proto +++ b/go-controller/vendor/k8s.io/api/coordination/v1beta1/generated.proto @@ -41,6 +41,75 @@ message Lease { optional LeaseSpec spec = 2; } +// LeaseCandidate defines a candidate for a Lease object. +// Candidates are created such that coordinated leader election will pick the best leader from the list of candidates. +message LeaseCandidate { + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; + + // spec contains the specification of the Lease. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + // +optional + optional LeaseCandidateSpec spec = 2; +} + +// LeaseCandidateList is a list of Lease objects. +message LeaseCandidateList { + // Standard list metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; + + // items is a list of schema objects. + repeated LeaseCandidate items = 2; +} + +// LeaseCandidateSpec is a specification of a Lease. +message LeaseCandidateSpec { + // LeaseName is the name of the lease for which this candidate is contending. + // The limits on this field are the same as on Lease.name. Multiple lease candidates + // may reference the same Lease.name. + // This field is immutable. + // +required + optional string leaseName = 1; + + // PingTime is the last time that the server has requested the LeaseCandidate + // to renew. It is only done during leader election to check if any + // LeaseCandidates have become ineligible. When PingTime is updated, the + // LeaseCandidate will respond by updating RenewTime. + // +optional + optional .k8s.io.apimachinery.pkg.apis.meta.v1.MicroTime pingTime = 2; + + // RenewTime is the time that the LeaseCandidate was last updated. + // Any time a Lease needs to do leader election, the PingTime field + // is updated to signal to the LeaseCandidate that they should update + // the RenewTime. + // Old LeaseCandidate objects are also garbage collected if it has been hours + // since the last renew. The PingTime field is updated regularly to prevent + // garbage collection for still active LeaseCandidates. + // +optional + optional .k8s.io.apimachinery.pkg.apis.meta.v1.MicroTime renewTime = 3; + + // BinaryVersion is the binary version. It must be in a semver format without leading `v`. + // This field is required. + // +required + optional string binaryVersion = 4; + + // EmulationVersion is the emulation version. It must be in a semver format without leading `v`. + // EmulationVersion must be less than or equal to BinaryVersion. + // This field is required when strategy is "OldestEmulationVersion" + // +optional + optional string emulationVersion = 5; + + // Strategy is the strategy that coordinated leader election will use for picking the leader. + // If multiple candidates for the same Lease return different strategies, the strategy provided + // by the candidate with the latest BinaryVersion will be used. If there is still conflict, + // this is a user error and coordinated leader election will not operate the Lease until resolved. + // +required + optional string strategy = 6; +} + // LeaseList is a list of Lease objects. message LeaseList { // Standard list metadata. diff --git a/go-controller/vendor/k8s.io/api/coordination/v1beta1/register.go b/go-controller/vendor/k8s.io/api/coordination/v1beta1/register.go index 85efaa64e7..bd00164233 100644 --- a/go-controller/vendor/k8s.io/api/coordination/v1beta1/register.go +++ b/go-controller/vendor/k8s.io/api/coordination/v1beta1/register.go @@ -46,6 +46,8 @@ func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, &Lease{}, &LeaseList{}, + &LeaseCandidate{}, + &LeaseCandidateList{}, ) metav1.AddToGroupVersion(scheme, SchemeGroupVersion) diff --git a/go-controller/vendor/k8s.io/api/coordination/v1beta1/types.go b/go-controller/vendor/k8s.io/api/coordination/v1beta1/types.go index d63fc30a9e..781d29efce 100644 --- a/go-controller/vendor/k8s.io/api/coordination/v1beta1/types.go +++ b/go-controller/vendor/k8s.io/api/coordination/v1beta1/types.go @@ -91,3 +91,76 @@ type LeaseList struct { // items is a list of schema objects. Items []Lease `json:"items" protobuf:"bytes,2,rep,name=items"` } + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.33 + +// LeaseCandidate defines a candidate for a Lease object. +// Candidates are created such that coordinated leader election will pick the best leader from the list of candidates. +type LeaseCandidate struct { + metav1.TypeMeta `json:",inline"` + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // spec contains the specification of the Lease. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + // +optional + Spec LeaseCandidateSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` +} + +// LeaseCandidateSpec is a specification of a Lease. +type LeaseCandidateSpec struct { + // LeaseName is the name of the lease for which this candidate is contending. + // The limits on this field are the same as on Lease.name. Multiple lease candidates + // may reference the same Lease.name. + // This field is immutable. + // +required + LeaseName string `json:"leaseName" protobuf:"bytes,1,name=leaseName"` + // PingTime is the last time that the server has requested the LeaseCandidate + // to renew. It is only done during leader election to check if any + // LeaseCandidates have become ineligible. When PingTime is updated, the + // LeaseCandidate will respond by updating RenewTime. + // +optional + PingTime *metav1.MicroTime `json:"pingTime,omitempty" protobuf:"bytes,2,opt,name=pingTime"` + // RenewTime is the time that the LeaseCandidate was last updated. + // Any time a Lease needs to do leader election, the PingTime field + // is updated to signal to the LeaseCandidate that they should update + // the RenewTime. + // Old LeaseCandidate objects are also garbage collected if it has been hours + // since the last renew. The PingTime field is updated regularly to prevent + // garbage collection for still active LeaseCandidates. + // +optional + RenewTime *metav1.MicroTime `json:"renewTime,omitempty" protobuf:"bytes,3,opt,name=renewTime"` + // BinaryVersion is the binary version. It must be in a semver format without leading `v`. + // This field is required. + // +required + BinaryVersion string `json:"binaryVersion" protobuf:"bytes,4,name=binaryVersion"` + // EmulationVersion is the emulation version. It must be in a semver format without leading `v`. + // EmulationVersion must be less than or equal to BinaryVersion. + // This field is required when strategy is "OldestEmulationVersion" + // +optional + EmulationVersion string `json:"emulationVersion,omitempty" protobuf:"bytes,5,opt,name=emulationVersion"` + // Strategy is the strategy that coordinated leader election will use for picking the leader. + // If multiple candidates for the same Lease return different strategies, the strategy provided + // by the candidate with the latest BinaryVersion will be used. If there is still conflict, + // this is a user error and coordinated leader election will not operate the Lease until resolved. + // +required + Strategy v1.CoordinatedLeaseStrategy `json:"strategy,omitempty" protobuf:"bytes,6,opt,name=strategy"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.33 + +// LeaseCandidateList is a list of Lease objects. +type LeaseCandidateList struct { + metav1.TypeMeta `json:",inline"` + // Standard list metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // items is a list of schema objects. + Items []LeaseCandidate `json:"items" protobuf:"bytes,2,rep,name=items"` +} diff --git a/go-controller/vendor/k8s.io/api/coordination/v1beta1/types_swagger_doc_generated.go b/go-controller/vendor/k8s.io/api/coordination/v1beta1/types_swagger_doc_generated.go index 50fe8ea189..35812b77f3 100644 --- a/go-controller/vendor/k8s.io/api/coordination/v1beta1/types_swagger_doc_generated.go +++ b/go-controller/vendor/k8s.io/api/coordination/v1beta1/types_swagger_doc_generated.go @@ -37,6 +37,40 @@ func (Lease) SwaggerDoc() map[string]string { return map_Lease } +var map_LeaseCandidate = map[string]string{ + "": "LeaseCandidate defines a candidate for a Lease object. Candidates are created such that coordinated leader election will pick the best leader from the list of candidates.", + "metadata": "More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "spec": "spec contains the specification of the Lease. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", +} + +func (LeaseCandidate) SwaggerDoc() map[string]string { + return map_LeaseCandidate +} + +var map_LeaseCandidateList = map[string]string{ + "": "LeaseCandidateList is a list of Lease objects.", + "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "items": "items is a list of schema objects.", +} + +func (LeaseCandidateList) SwaggerDoc() map[string]string { + return map_LeaseCandidateList +} + +var map_LeaseCandidateSpec = map[string]string{ + "": "LeaseCandidateSpec is a specification of a Lease.", + "leaseName": "LeaseName is the name of the lease for which this candidate is contending. The limits on this field are the same as on Lease.name. Multiple lease candidates may reference the same Lease.name. This field is immutable.", + "pingTime": "PingTime is the last time that the server has requested the LeaseCandidate to renew. It is only done during leader election to check if any LeaseCandidates have become ineligible. When PingTime is updated, the LeaseCandidate will respond by updating RenewTime.", + "renewTime": "RenewTime is the time that the LeaseCandidate was last updated. Any time a Lease needs to do leader election, the PingTime field is updated to signal to the LeaseCandidate that they should update the RenewTime. Old LeaseCandidate objects are also garbage collected if it has been hours since the last renew. The PingTime field is updated regularly to prevent garbage collection for still active LeaseCandidates.", + "binaryVersion": "BinaryVersion is the binary version. It must be in a semver format without leading `v`. This field is required.", + "emulationVersion": "EmulationVersion is the emulation version. It must be in a semver format without leading `v`. EmulationVersion must be less than or equal to BinaryVersion. This field is required when strategy is \"OldestEmulationVersion\"", + "strategy": "Strategy is the strategy that coordinated leader election will use for picking the leader. If multiple candidates for the same Lease return different strategies, the strategy provided by the candidate with the latest BinaryVersion will be used. If there is still conflict, this is a user error and coordinated leader election will not operate the Lease until resolved.", +} + +func (LeaseCandidateSpec) SwaggerDoc() map[string]string { + return map_LeaseCandidateSpec +} + var map_LeaseList = map[string]string{ "": "LeaseList is a list of Lease objects.", "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", diff --git a/go-controller/vendor/k8s.io/api/coordination/v1beta1/zz_generated.deepcopy.go b/go-controller/vendor/k8s.io/api/coordination/v1beta1/zz_generated.deepcopy.go index dcef1e346a..b990ee247f 100644 --- a/go-controller/vendor/k8s.io/api/coordination/v1beta1/zz_generated.deepcopy.go +++ b/go-controller/vendor/k8s.io/api/coordination/v1beta1/zz_generated.deepcopy.go @@ -53,6 +53,90 @@ func (in *Lease) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LeaseCandidate) DeepCopyInto(out *LeaseCandidate) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LeaseCandidate. +func (in *LeaseCandidate) DeepCopy() *LeaseCandidate { + if in == nil { + return nil + } + out := new(LeaseCandidate) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *LeaseCandidate) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LeaseCandidateList) DeepCopyInto(out *LeaseCandidateList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]LeaseCandidate, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LeaseCandidateList. +func (in *LeaseCandidateList) DeepCopy() *LeaseCandidateList { + if in == nil { + return nil + } + out := new(LeaseCandidateList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *LeaseCandidateList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LeaseCandidateSpec) DeepCopyInto(out *LeaseCandidateSpec) { + *out = *in + if in.PingTime != nil { + in, out := &in.PingTime, &out.PingTime + *out = (*in).DeepCopy() + } + if in.RenewTime != nil { + in, out := &in.RenewTime, &out.RenewTime + *out = (*in).DeepCopy() + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LeaseCandidateSpec. +func (in *LeaseCandidateSpec) DeepCopy() *LeaseCandidateSpec { + if in == nil { + return nil + } + out := new(LeaseCandidateSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *LeaseList) DeepCopyInto(out *LeaseList) { *out = *in diff --git a/go-controller/vendor/k8s.io/api/coordination/v1beta1/zz_generated.prerelease-lifecycle.go b/go-controller/vendor/k8s.io/api/coordination/v1beta1/zz_generated.prerelease-lifecycle.go index 18926aa108..73636edfa3 100644 --- a/go-controller/vendor/k8s.io/api/coordination/v1beta1/zz_generated.prerelease-lifecycle.go +++ b/go-controller/vendor/k8s.io/api/coordination/v1beta1/zz_generated.prerelease-lifecycle.go @@ -49,6 +49,42 @@ func (in *Lease) APILifecycleRemoved() (major, minor int) { return 1, 22 } +// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. +func (in *LeaseCandidate) APILifecycleIntroduced() (major, minor int) { + return 1, 33 +} + +// APILifecycleDeprecated is an autogenerated function, returning the release in which the API struct was or will be deprecated as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:deprecated" tags in types.go or "k8s:prerelease-lifecycle-gen:introduced" plus three minor. +func (in *LeaseCandidate) APILifecycleDeprecated() (major, minor int) { + return 1, 36 +} + +// APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. +func (in *LeaseCandidate) APILifecycleRemoved() (major, minor int) { + return 1, 39 +} + +// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. +func (in *LeaseCandidateList) APILifecycleIntroduced() (major, minor int) { + return 1, 33 +} + +// APILifecycleDeprecated is an autogenerated function, returning the release in which the API struct was or will be deprecated as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:deprecated" tags in types.go or "k8s:prerelease-lifecycle-gen:introduced" plus three minor. +func (in *LeaseCandidateList) APILifecycleDeprecated() (major, minor int) { + return 1, 36 +} + +// APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. +func (in *LeaseCandidateList) APILifecycleRemoved() (major, minor int) { + return 1, 39 +} + // APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. // It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. func (in *LeaseList) APILifecycleIntroduced() (major, minor int) { diff --git a/go-controller/vendor/k8s.io/api/core/v1/doc.go b/go-controller/vendor/k8s.io/api/core/v1/doc.go index bc0041b331..e4e9196aeb 100644 --- a/go-controller/vendor/k8s.io/api/core/v1/doc.go +++ b/go-controller/vendor/k8s.io/api/core/v1/doc.go @@ -21,4 +21,4 @@ limitations under the License. // +groupName= // Package v1 is the v1 version of the core API. -package v1 // import "k8s.io/api/core/v1" +package v1 diff --git a/go-controller/vendor/k8s.io/api/core/v1/generated.pb.go b/go-controller/vendor/k8s.io/api/core/v1/generated.pb.go index 9d466c6d79..a4b8f58429 100644 --- a/go-controller/vendor/k8s.io/api/core/v1/generated.pb.go +++ b/go-controller/vendor/k8s.io/api/core/v1/generated.pb.go @@ -3213,10 +3213,38 @@ func (m *NodeStatus) XXX_DiscardUnknown() { var xxx_messageInfo_NodeStatus proto.InternalMessageInfo +func (m *NodeSwapStatus) Reset() { *m = NodeSwapStatus{} } +func (*NodeSwapStatus) ProtoMessage() {} +func (*NodeSwapStatus) Descriptor() ([]byte, []int) { + return fileDescriptor_6c07b07c062484ab, []int{113} +} +func (m *NodeSwapStatus) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *NodeSwapStatus) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *NodeSwapStatus) XXX_Merge(src proto.Message) { + xxx_messageInfo_NodeSwapStatus.Merge(m, src) +} +func (m *NodeSwapStatus) XXX_Size() int { + return m.Size() +} +func (m *NodeSwapStatus) XXX_DiscardUnknown() { + xxx_messageInfo_NodeSwapStatus.DiscardUnknown(m) +} + +var xxx_messageInfo_NodeSwapStatus proto.InternalMessageInfo + func (m *NodeSystemInfo) Reset() { *m = NodeSystemInfo{} } func (*NodeSystemInfo) ProtoMessage() {} func (*NodeSystemInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{113} + return fileDescriptor_6c07b07c062484ab, []int{114} } func (m *NodeSystemInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3244,7 +3272,7 @@ var xxx_messageInfo_NodeSystemInfo proto.InternalMessageInfo func (m *ObjectFieldSelector) Reset() { *m = ObjectFieldSelector{} } func (*ObjectFieldSelector) ProtoMessage() {} func (*ObjectFieldSelector) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{114} + return fileDescriptor_6c07b07c062484ab, []int{115} } func (m *ObjectFieldSelector) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3272,7 +3300,7 @@ var xxx_messageInfo_ObjectFieldSelector proto.InternalMessageInfo func (m *ObjectReference) Reset() { *m = ObjectReference{} } func (*ObjectReference) ProtoMessage() {} func (*ObjectReference) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{115} + return fileDescriptor_6c07b07c062484ab, []int{116} } func (m *ObjectReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3300,7 +3328,7 @@ var xxx_messageInfo_ObjectReference proto.InternalMessageInfo func (m *PersistentVolume) Reset() { *m = PersistentVolume{} } func (*PersistentVolume) ProtoMessage() {} func (*PersistentVolume) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{116} + return fileDescriptor_6c07b07c062484ab, []int{117} } func (m *PersistentVolume) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3328,7 +3356,7 @@ var xxx_messageInfo_PersistentVolume proto.InternalMessageInfo func (m *PersistentVolumeClaim) Reset() { *m = PersistentVolumeClaim{} } func (*PersistentVolumeClaim) ProtoMessage() {} func (*PersistentVolumeClaim) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{117} + return fileDescriptor_6c07b07c062484ab, []int{118} } func (m *PersistentVolumeClaim) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3356,7 +3384,7 @@ var xxx_messageInfo_PersistentVolumeClaim proto.InternalMessageInfo func (m *PersistentVolumeClaimCondition) Reset() { *m = PersistentVolumeClaimCondition{} } func (*PersistentVolumeClaimCondition) ProtoMessage() {} func (*PersistentVolumeClaimCondition) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{118} + return fileDescriptor_6c07b07c062484ab, []int{119} } func (m *PersistentVolumeClaimCondition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3384,7 +3412,7 @@ var xxx_messageInfo_PersistentVolumeClaimCondition proto.InternalMessageInfo func (m *PersistentVolumeClaimList) Reset() { *m = PersistentVolumeClaimList{} } func (*PersistentVolumeClaimList) ProtoMessage() {} func (*PersistentVolumeClaimList) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{119} + return fileDescriptor_6c07b07c062484ab, []int{120} } func (m *PersistentVolumeClaimList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3412,7 +3440,7 @@ var xxx_messageInfo_PersistentVolumeClaimList proto.InternalMessageInfo func (m *PersistentVolumeClaimSpec) Reset() { *m = PersistentVolumeClaimSpec{} } func (*PersistentVolumeClaimSpec) ProtoMessage() {} func (*PersistentVolumeClaimSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{120} + return fileDescriptor_6c07b07c062484ab, []int{121} } func (m *PersistentVolumeClaimSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3440,7 +3468,7 @@ var xxx_messageInfo_PersistentVolumeClaimSpec proto.InternalMessageInfo func (m *PersistentVolumeClaimStatus) Reset() { *m = PersistentVolumeClaimStatus{} } func (*PersistentVolumeClaimStatus) ProtoMessage() {} func (*PersistentVolumeClaimStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{121} + return fileDescriptor_6c07b07c062484ab, []int{122} } func (m *PersistentVolumeClaimStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3468,7 +3496,7 @@ var xxx_messageInfo_PersistentVolumeClaimStatus proto.InternalMessageInfo func (m *PersistentVolumeClaimTemplate) Reset() { *m = PersistentVolumeClaimTemplate{} } func (*PersistentVolumeClaimTemplate) ProtoMessage() {} func (*PersistentVolumeClaimTemplate) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{122} + return fileDescriptor_6c07b07c062484ab, []int{123} } func (m *PersistentVolumeClaimTemplate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3496,7 +3524,7 @@ var xxx_messageInfo_PersistentVolumeClaimTemplate proto.InternalMessageInfo func (m *PersistentVolumeClaimVolumeSource) Reset() { *m = PersistentVolumeClaimVolumeSource{} } func (*PersistentVolumeClaimVolumeSource) ProtoMessage() {} func (*PersistentVolumeClaimVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{123} + return fileDescriptor_6c07b07c062484ab, []int{124} } func (m *PersistentVolumeClaimVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3524,7 +3552,7 @@ var xxx_messageInfo_PersistentVolumeClaimVolumeSource proto.InternalMessageInfo func (m *PersistentVolumeList) Reset() { *m = PersistentVolumeList{} } func (*PersistentVolumeList) ProtoMessage() {} func (*PersistentVolumeList) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{124} + return fileDescriptor_6c07b07c062484ab, []int{125} } func (m *PersistentVolumeList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3552,7 +3580,7 @@ var xxx_messageInfo_PersistentVolumeList proto.InternalMessageInfo func (m *PersistentVolumeSource) Reset() { *m = PersistentVolumeSource{} } func (*PersistentVolumeSource) ProtoMessage() {} func (*PersistentVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{125} + return fileDescriptor_6c07b07c062484ab, []int{126} } func (m *PersistentVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3580,7 +3608,7 @@ var xxx_messageInfo_PersistentVolumeSource proto.InternalMessageInfo func (m *PersistentVolumeSpec) Reset() { *m = PersistentVolumeSpec{} } func (*PersistentVolumeSpec) ProtoMessage() {} func (*PersistentVolumeSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{126} + return fileDescriptor_6c07b07c062484ab, []int{127} } func (m *PersistentVolumeSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3608,7 +3636,7 @@ var xxx_messageInfo_PersistentVolumeSpec proto.InternalMessageInfo func (m *PersistentVolumeStatus) Reset() { *m = PersistentVolumeStatus{} } func (*PersistentVolumeStatus) ProtoMessage() {} func (*PersistentVolumeStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{127} + return fileDescriptor_6c07b07c062484ab, []int{128} } func (m *PersistentVolumeStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3636,7 +3664,7 @@ var xxx_messageInfo_PersistentVolumeStatus proto.InternalMessageInfo func (m *PhotonPersistentDiskVolumeSource) Reset() { *m = PhotonPersistentDiskVolumeSource{} } func (*PhotonPersistentDiskVolumeSource) ProtoMessage() {} func (*PhotonPersistentDiskVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{128} + return fileDescriptor_6c07b07c062484ab, []int{129} } func (m *PhotonPersistentDiskVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3664,7 +3692,7 @@ var xxx_messageInfo_PhotonPersistentDiskVolumeSource proto.InternalMessageInfo func (m *Pod) Reset() { *m = Pod{} } func (*Pod) ProtoMessage() {} func (*Pod) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{129} + return fileDescriptor_6c07b07c062484ab, []int{130} } func (m *Pod) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3692,7 +3720,7 @@ var xxx_messageInfo_Pod proto.InternalMessageInfo func (m *PodAffinity) Reset() { *m = PodAffinity{} } func (*PodAffinity) ProtoMessage() {} func (*PodAffinity) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{130} + return fileDescriptor_6c07b07c062484ab, []int{131} } func (m *PodAffinity) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3720,7 +3748,7 @@ var xxx_messageInfo_PodAffinity proto.InternalMessageInfo func (m *PodAffinityTerm) Reset() { *m = PodAffinityTerm{} } func (*PodAffinityTerm) ProtoMessage() {} func (*PodAffinityTerm) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{131} + return fileDescriptor_6c07b07c062484ab, []int{132} } func (m *PodAffinityTerm) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3748,7 +3776,7 @@ var xxx_messageInfo_PodAffinityTerm proto.InternalMessageInfo func (m *PodAntiAffinity) Reset() { *m = PodAntiAffinity{} } func (*PodAntiAffinity) ProtoMessage() {} func (*PodAntiAffinity) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{132} + return fileDescriptor_6c07b07c062484ab, []int{133} } func (m *PodAntiAffinity) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3776,7 +3804,7 @@ var xxx_messageInfo_PodAntiAffinity proto.InternalMessageInfo func (m *PodAttachOptions) Reset() { *m = PodAttachOptions{} } func (*PodAttachOptions) ProtoMessage() {} func (*PodAttachOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{133} + return fileDescriptor_6c07b07c062484ab, []int{134} } func (m *PodAttachOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3804,7 +3832,7 @@ var xxx_messageInfo_PodAttachOptions proto.InternalMessageInfo func (m *PodCondition) Reset() { *m = PodCondition{} } func (*PodCondition) ProtoMessage() {} func (*PodCondition) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{134} + return fileDescriptor_6c07b07c062484ab, []int{135} } func (m *PodCondition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3832,7 +3860,7 @@ var xxx_messageInfo_PodCondition proto.InternalMessageInfo func (m *PodDNSConfig) Reset() { *m = PodDNSConfig{} } func (*PodDNSConfig) ProtoMessage() {} func (*PodDNSConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{135} + return fileDescriptor_6c07b07c062484ab, []int{136} } func (m *PodDNSConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3860,7 +3888,7 @@ var xxx_messageInfo_PodDNSConfig proto.InternalMessageInfo func (m *PodDNSConfigOption) Reset() { *m = PodDNSConfigOption{} } func (*PodDNSConfigOption) ProtoMessage() {} func (*PodDNSConfigOption) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{136} + return fileDescriptor_6c07b07c062484ab, []int{137} } func (m *PodDNSConfigOption) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3888,7 +3916,7 @@ var xxx_messageInfo_PodDNSConfigOption proto.InternalMessageInfo func (m *PodExecOptions) Reset() { *m = PodExecOptions{} } func (*PodExecOptions) ProtoMessage() {} func (*PodExecOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{137} + return fileDescriptor_6c07b07c062484ab, []int{138} } func (m *PodExecOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3916,7 +3944,7 @@ var xxx_messageInfo_PodExecOptions proto.InternalMessageInfo func (m *PodIP) Reset() { *m = PodIP{} } func (*PodIP) ProtoMessage() {} func (*PodIP) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{138} + return fileDescriptor_6c07b07c062484ab, []int{139} } func (m *PodIP) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3944,7 +3972,7 @@ var xxx_messageInfo_PodIP proto.InternalMessageInfo func (m *PodList) Reset() { *m = PodList{} } func (*PodList) ProtoMessage() {} func (*PodList) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{139} + return fileDescriptor_6c07b07c062484ab, []int{140} } func (m *PodList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3972,7 +4000,7 @@ var xxx_messageInfo_PodList proto.InternalMessageInfo func (m *PodLogOptions) Reset() { *m = PodLogOptions{} } func (*PodLogOptions) ProtoMessage() {} func (*PodLogOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{140} + return fileDescriptor_6c07b07c062484ab, []int{141} } func (m *PodLogOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4000,7 +4028,7 @@ var xxx_messageInfo_PodLogOptions proto.InternalMessageInfo func (m *PodOS) Reset() { *m = PodOS{} } func (*PodOS) ProtoMessage() {} func (*PodOS) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{141} + return fileDescriptor_6c07b07c062484ab, []int{142} } func (m *PodOS) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4028,7 +4056,7 @@ var xxx_messageInfo_PodOS proto.InternalMessageInfo func (m *PodPortForwardOptions) Reset() { *m = PodPortForwardOptions{} } func (*PodPortForwardOptions) ProtoMessage() {} func (*PodPortForwardOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{142} + return fileDescriptor_6c07b07c062484ab, []int{143} } func (m *PodPortForwardOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4056,7 +4084,7 @@ var xxx_messageInfo_PodPortForwardOptions proto.InternalMessageInfo func (m *PodProxyOptions) Reset() { *m = PodProxyOptions{} } func (*PodProxyOptions) ProtoMessage() {} func (*PodProxyOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{143} + return fileDescriptor_6c07b07c062484ab, []int{144} } func (m *PodProxyOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4084,7 +4112,7 @@ var xxx_messageInfo_PodProxyOptions proto.InternalMessageInfo func (m *PodReadinessGate) Reset() { *m = PodReadinessGate{} } func (*PodReadinessGate) ProtoMessage() {} func (*PodReadinessGate) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{144} + return fileDescriptor_6c07b07c062484ab, []int{145} } func (m *PodReadinessGate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4112,7 +4140,7 @@ var xxx_messageInfo_PodReadinessGate proto.InternalMessageInfo func (m *PodResourceClaim) Reset() { *m = PodResourceClaim{} } func (*PodResourceClaim) ProtoMessage() {} func (*PodResourceClaim) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{145} + return fileDescriptor_6c07b07c062484ab, []int{146} } func (m *PodResourceClaim) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4140,7 +4168,7 @@ var xxx_messageInfo_PodResourceClaim proto.InternalMessageInfo func (m *PodResourceClaimStatus) Reset() { *m = PodResourceClaimStatus{} } func (*PodResourceClaimStatus) ProtoMessage() {} func (*PodResourceClaimStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{146} + return fileDescriptor_6c07b07c062484ab, []int{147} } func (m *PodResourceClaimStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4168,7 +4196,7 @@ var xxx_messageInfo_PodResourceClaimStatus proto.InternalMessageInfo func (m *PodSchedulingGate) Reset() { *m = PodSchedulingGate{} } func (*PodSchedulingGate) ProtoMessage() {} func (*PodSchedulingGate) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{147} + return fileDescriptor_6c07b07c062484ab, []int{148} } func (m *PodSchedulingGate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4196,7 +4224,7 @@ var xxx_messageInfo_PodSchedulingGate proto.InternalMessageInfo func (m *PodSecurityContext) Reset() { *m = PodSecurityContext{} } func (*PodSecurityContext) ProtoMessage() {} func (*PodSecurityContext) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{148} + return fileDescriptor_6c07b07c062484ab, []int{149} } func (m *PodSecurityContext) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4224,7 +4252,7 @@ var xxx_messageInfo_PodSecurityContext proto.InternalMessageInfo func (m *PodSignature) Reset() { *m = PodSignature{} } func (*PodSignature) ProtoMessage() {} func (*PodSignature) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{149} + return fileDescriptor_6c07b07c062484ab, []int{150} } func (m *PodSignature) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4252,7 +4280,7 @@ var xxx_messageInfo_PodSignature proto.InternalMessageInfo func (m *PodSpec) Reset() { *m = PodSpec{} } func (*PodSpec) ProtoMessage() {} func (*PodSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{150} + return fileDescriptor_6c07b07c062484ab, []int{151} } func (m *PodSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4280,7 +4308,7 @@ var xxx_messageInfo_PodSpec proto.InternalMessageInfo func (m *PodStatus) Reset() { *m = PodStatus{} } func (*PodStatus) ProtoMessage() {} func (*PodStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{151} + return fileDescriptor_6c07b07c062484ab, []int{152} } func (m *PodStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4308,7 +4336,7 @@ var xxx_messageInfo_PodStatus proto.InternalMessageInfo func (m *PodStatusResult) Reset() { *m = PodStatusResult{} } func (*PodStatusResult) ProtoMessage() {} func (*PodStatusResult) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{152} + return fileDescriptor_6c07b07c062484ab, []int{153} } func (m *PodStatusResult) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4336,7 +4364,7 @@ var xxx_messageInfo_PodStatusResult proto.InternalMessageInfo func (m *PodTemplate) Reset() { *m = PodTemplate{} } func (*PodTemplate) ProtoMessage() {} func (*PodTemplate) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{153} + return fileDescriptor_6c07b07c062484ab, []int{154} } func (m *PodTemplate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4364,7 +4392,7 @@ var xxx_messageInfo_PodTemplate proto.InternalMessageInfo func (m *PodTemplateList) Reset() { *m = PodTemplateList{} } func (*PodTemplateList) ProtoMessage() {} func (*PodTemplateList) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{154} + return fileDescriptor_6c07b07c062484ab, []int{155} } func (m *PodTemplateList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4392,7 +4420,7 @@ var xxx_messageInfo_PodTemplateList proto.InternalMessageInfo func (m *PodTemplateSpec) Reset() { *m = PodTemplateSpec{} } func (*PodTemplateSpec) ProtoMessage() {} func (*PodTemplateSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{155} + return fileDescriptor_6c07b07c062484ab, []int{156} } func (m *PodTemplateSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4420,7 +4448,7 @@ var xxx_messageInfo_PodTemplateSpec proto.InternalMessageInfo func (m *PortStatus) Reset() { *m = PortStatus{} } func (*PortStatus) ProtoMessage() {} func (*PortStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{156} + return fileDescriptor_6c07b07c062484ab, []int{157} } func (m *PortStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4448,7 +4476,7 @@ var xxx_messageInfo_PortStatus proto.InternalMessageInfo func (m *PortworxVolumeSource) Reset() { *m = PortworxVolumeSource{} } func (*PortworxVolumeSource) ProtoMessage() {} func (*PortworxVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{157} + return fileDescriptor_6c07b07c062484ab, []int{158} } func (m *PortworxVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4476,7 +4504,7 @@ var xxx_messageInfo_PortworxVolumeSource proto.InternalMessageInfo func (m *Preconditions) Reset() { *m = Preconditions{} } func (*Preconditions) ProtoMessage() {} func (*Preconditions) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{158} + return fileDescriptor_6c07b07c062484ab, []int{159} } func (m *Preconditions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4504,7 +4532,7 @@ var xxx_messageInfo_Preconditions proto.InternalMessageInfo func (m *PreferAvoidPodsEntry) Reset() { *m = PreferAvoidPodsEntry{} } func (*PreferAvoidPodsEntry) ProtoMessage() {} func (*PreferAvoidPodsEntry) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{159} + return fileDescriptor_6c07b07c062484ab, []int{160} } func (m *PreferAvoidPodsEntry) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4532,7 +4560,7 @@ var xxx_messageInfo_PreferAvoidPodsEntry proto.InternalMessageInfo func (m *PreferredSchedulingTerm) Reset() { *m = PreferredSchedulingTerm{} } func (*PreferredSchedulingTerm) ProtoMessage() {} func (*PreferredSchedulingTerm) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{160} + return fileDescriptor_6c07b07c062484ab, []int{161} } func (m *PreferredSchedulingTerm) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4560,7 +4588,7 @@ var xxx_messageInfo_PreferredSchedulingTerm proto.InternalMessageInfo func (m *Probe) Reset() { *m = Probe{} } func (*Probe) ProtoMessage() {} func (*Probe) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{161} + return fileDescriptor_6c07b07c062484ab, []int{162} } func (m *Probe) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4588,7 +4616,7 @@ var xxx_messageInfo_Probe proto.InternalMessageInfo func (m *ProbeHandler) Reset() { *m = ProbeHandler{} } func (*ProbeHandler) ProtoMessage() {} func (*ProbeHandler) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{162} + return fileDescriptor_6c07b07c062484ab, []int{163} } func (m *ProbeHandler) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4616,7 +4644,7 @@ var xxx_messageInfo_ProbeHandler proto.InternalMessageInfo func (m *ProjectedVolumeSource) Reset() { *m = ProjectedVolumeSource{} } func (*ProjectedVolumeSource) ProtoMessage() {} func (*ProjectedVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{163} + return fileDescriptor_6c07b07c062484ab, []int{164} } func (m *ProjectedVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4644,7 +4672,7 @@ var xxx_messageInfo_ProjectedVolumeSource proto.InternalMessageInfo func (m *QuobyteVolumeSource) Reset() { *m = QuobyteVolumeSource{} } func (*QuobyteVolumeSource) ProtoMessage() {} func (*QuobyteVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{164} + return fileDescriptor_6c07b07c062484ab, []int{165} } func (m *QuobyteVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4672,7 +4700,7 @@ var xxx_messageInfo_QuobyteVolumeSource proto.InternalMessageInfo func (m *RBDPersistentVolumeSource) Reset() { *m = RBDPersistentVolumeSource{} } func (*RBDPersistentVolumeSource) ProtoMessage() {} func (*RBDPersistentVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{165} + return fileDescriptor_6c07b07c062484ab, []int{166} } func (m *RBDPersistentVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4700,7 +4728,7 @@ var xxx_messageInfo_RBDPersistentVolumeSource proto.InternalMessageInfo func (m *RBDVolumeSource) Reset() { *m = RBDVolumeSource{} } func (*RBDVolumeSource) ProtoMessage() {} func (*RBDVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{166} + return fileDescriptor_6c07b07c062484ab, []int{167} } func (m *RBDVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4728,7 +4756,7 @@ var xxx_messageInfo_RBDVolumeSource proto.InternalMessageInfo func (m *RangeAllocation) Reset() { *m = RangeAllocation{} } func (*RangeAllocation) ProtoMessage() {} func (*RangeAllocation) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{167} + return fileDescriptor_6c07b07c062484ab, []int{168} } func (m *RangeAllocation) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4756,7 +4784,7 @@ var xxx_messageInfo_RangeAllocation proto.InternalMessageInfo func (m *ReplicationController) Reset() { *m = ReplicationController{} } func (*ReplicationController) ProtoMessage() {} func (*ReplicationController) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{168} + return fileDescriptor_6c07b07c062484ab, []int{169} } func (m *ReplicationController) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4784,7 +4812,7 @@ var xxx_messageInfo_ReplicationController proto.InternalMessageInfo func (m *ReplicationControllerCondition) Reset() { *m = ReplicationControllerCondition{} } func (*ReplicationControllerCondition) ProtoMessage() {} func (*ReplicationControllerCondition) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{169} + return fileDescriptor_6c07b07c062484ab, []int{170} } func (m *ReplicationControllerCondition) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4812,7 +4840,7 @@ var xxx_messageInfo_ReplicationControllerCondition proto.InternalMessageInfo func (m *ReplicationControllerList) Reset() { *m = ReplicationControllerList{} } func (*ReplicationControllerList) ProtoMessage() {} func (*ReplicationControllerList) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{170} + return fileDescriptor_6c07b07c062484ab, []int{171} } func (m *ReplicationControllerList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4840,7 +4868,7 @@ var xxx_messageInfo_ReplicationControllerList proto.InternalMessageInfo func (m *ReplicationControllerSpec) Reset() { *m = ReplicationControllerSpec{} } func (*ReplicationControllerSpec) ProtoMessage() {} func (*ReplicationControllerSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{171} + return fileDescriptor_6c07b07c062484ab, []int{172} } func (m *ReplicationControllerSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4868,7 +4896,7 @@ var xxx_messageInfo_ReplicationControllerSpec proto.InternalMessageInfo func (m *ReplicationControllerStatus) Reset() { *m = ReplicationControllerStatus{} } func (*ReplicationControllerStatus) ProtoMessage() {} func (*ReplicationControllerStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{172} + return fileDescriptor_6c07b07c062484ab, []int{173} } func (m *ReplicationControllerStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4896,7 +4924,7 @@ var xxx_messageInfo_ReplicationControllerStatus proto.InternalMessageInfo func (m *ResourceClaim) Reset() { *m = ResourceClaim{} } func (*ResourceClaim) ProtoMessage() {} func (*ResourceClaim) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{173} + return fileDescriptor_6c07b07c062484ab, []int{174} } func (m *ResourceClaim) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4924,7 +4952,7 @@ var xxx_messageInfo_ResourceClaim proto.InternalMessageInfo func (m *ResourceFieldSelector) Reset() { *m = ResourceFieldSelector{} } func (*ResourceFieldSelector) ProtoMessage() {} func (*ResourceFieldSelector) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{174} + return fileDescriptor_6c07b07c062484ab, []int{175} } func (m *ResourceFieldSelector) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4952,7 +4980,7 @@ var xxx_messageInfo_ResourceFieldSelector proto.InternalMessageInfo func (m *ResourceHealth) Reset() { *m = ResourceHealth{} } func (*ResourceHealth) ProtoMessage() {} func (*ResourceHealth) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{175} + return fileDescriptor_6c07b07c062484ab, []int{176} } func (m *ResourceHealth) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4980,7 +5008,7 @@ var xxx_messageInfo_ResourceHealth proto.InternalMessageInfo func (m *ResourceQuota) Reset() { *m = ResourceQuota{} } func (*ResourceQuota) ProtoMessage() {} func (*ResourceQuota) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{176} + return fileDescriptor_6c07b07c062484ab, []int{177} } func (m *ResourceQuota) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5008,7 +5036,7 @@ var xxx_messageInfo_ResourceQuota proto.InternalMessageInfo func (m *ResourceQuotaList) Reset() { *m = ResourceQuotaList{} } func (*ResourceQuotaList) ProtoMessage() {} func (*ResourceQuotaList) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{177} + return fileDescriptor_6c07b07c062484ab, []int{178} } func (m *ResourceQuotaList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5036,7 +5064,7 @@ var xxx_messageInfo_ResourceQuotaList proto.InternalMessageInfo func (m *ResourceQuotaSpec) Reset() { *m = ResourceQuotaSpec{} } func (*ResourceQuotaSpec) ProtoMessage() {} func (*ResourceQuotaSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{178} + return fileDescriptor_6c07b07c062484ab, []int{179} } func (m *ResourceQuotaSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5064,7 +5092,7 @@ var xxx_messageInfo_ResourceQuotaSpec proto.InternalMessageInfo func (m *ResourceQuotaStatus) Reset() { *m = ResourceQuotaStatus{} } func (*ResourceQuotaStatus) ProtoMessage() {} func (*ResourceQuotaStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{179} + return fileDescriptor_6c07b07c062484ab, []int{180} } func (m *ResourceQuotaStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5092,7 +5120,7 @@ var xxx_messageInfo_ResourceQuotaStatus proto.InternalMessageInfo func (m *ResourceRequirements) Reset() { *m = ResourceRequirements{} } func (*ResourceRequirements) ProtoMessage() {} func (*ResourceRequirements) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{180} + return fileDescriptor_6c07b07c062484ab, []int{181} } func (m *ResourceRequirements) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5120,7 +5148,7 @@ var xxx_messageInfo_ResourceRequirements proto.InternalMessageInfo func (m *ResourceStatus) Reset() { *m = ResourceStatus{} } func (*ResourceStatus) ProtoMessage() {} func (*ResourceStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{181} + return fileDescriptor_6c07b07c062484ab, []int{182} } func (m *ResourceStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5148,7 +5176,7 @@ var xxx_messageInfo_ResourceStatus proto.InternalMessageInfo func (m *SELinuxOptions) Reset() { *m = SELinuxOptions{} } func (*SELinuxOptions) ProtoMessage() {} func (*SELinuxOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{182} + return fileDescriptor_6c07b07c062484ab, []int{183} } func (m *SELinuxOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5176,7 +5204,7 @@ var xxx_messageInfo_SELinuxOptions proto.InternalMessageInfo func (m *ScaleIOPersistentVolumeSource) Reset() { *m = ScaleIOPersistentVolumeSource{} } func (*ScaleIOPersistentVolumeSource) ProtoMessage() {} func (*ScaleIOPersistentVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{183} + return fileDescriptor_6c07b07c062484ab, []int{184} } func (m *ScaleIOPersistentVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5204,7 +5232,7 @@ var xxx_messageInfo_ScaleIOPersistentVolumeSource proto.InternalMessageInfo func (m *ScaleIOVolumeSource) Reset() { *m = ScaleIOVolumeSource{} } func (*ScaleIOVolumeSource) ProtoMessage() {} func (*ScaleIOVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{184} + return fileDescriptor_6c07b07c062484ab, []int{185} } func (m *ScaleIOVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5232,7 +5260,7 @@ var xxx_messageInfo_ScaleIOVolumeSource proto.InternalMessageInfo func (m *ScopeSelector) Reset() { *m = ScopeSelector{} } func (*ScopeSelector) ProtoMessage() {} func (*ScopeSelector) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{185} + return fileDescriptor_6c07b07c062484ab, []int{186} } func (m *ScopeSelector) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5260,7 +5288,7 @@ var xxx_messageInfo_ScopeSelector proto.InternalMessageInfo func (m *ScopedResourceSelectorRequirement) Reset() { *m = ScopedResourceSelectorRequirement{} } func (*ScopedResourceSelectorRequirement) ProtoMessage() {} func (*ScopedResourceSelectorRequirement) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{186} + return fileDescriptor_6c07b07c062484ab, []int{187} } func (m *ScopedResourceSelectorRequirement) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5288,7 +5316,7 @@ var xxx_messageInfo_ScopedResourceSelectorRequirement proto.InternalMessageInfo func (m *SeccompProfile) Reset() { *m = SeccompProfile{} } func (*SeccompProfile) ProtoMessage() {} func (*SeccompProfile) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{187} + return fileDescriptor_6c07b07c062484ab, []int{188} } func (m *SeccompProfile) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5316,7 +5344,7 @@ var xxx_messageInfo_SeccompProfile proto.InternalMessageInfo func (m *Secret) Reset() { *m = Secret{} } func (*Secret) ProtoMessage() {} func (*Secret) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{188} + return fileDescriptor_6c07b07c062484ab, []int{189} } func (m *Secret) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5344,7 +5372,7 @@ var xxx_messageInfo_Secret proto.InternalMessageInfo func (m *SecretEnvSource) Reset() { *m = SecretEnvSource{} } func (*SecretEnvSource) ProtoMessage() {} func (*SecretEnvSource) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{189} + return fileDescriptor_6c07b07c062484ab, []int{190} } func (m *SecretEnvSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5372,7 +5400,7 @@ var xxx_messageInfo_SecretEnvSource proto.InternalMessageInfo func (m *SecretKeySelector) Reset() { *m = SecretKeySelector{} } func (*SecretKeySelector) ProtoMessage() {} func (*SecretKeySelector) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{190} + return fileDescriptor_6c07b07c062484ab, []int{191} } func (m *SecretKeySelector) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5400,7 +5428,7 @@ var xxx_messageInfo_SecretKeySelector proto.InternalMessageInfo func (m *SecretList) Reset() { *m = SecretList{} } func (*SecretList) ProtoMessage() {} func (*SecretList) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{191} + return fileDescriptor_6c07b07c062484ab, []int{192} } func (m *SecretList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5428,7 +5456,7 @@ var xxx_messageInfo_SecretList proto.InternalMessageInfo func (m *SecretProjection) Reset() { *m = SecretProjection{} } func (*SecretProjection) ProtoMessage() {} func (*SecretProjection) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{192} + return fileDescriptor_6c07b07c062484ab, []int{193} } func (m *SecretProjection) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5456,7 +5484,7 @@ var xxx_messageInfo_SecretProjection proto.InternalMessageInfo func (m *SecretReference) Reset() { *m = SecretReference{} } func (*SecretReference) ProtoMessage() {} func (*SecretReference) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{193} + return fileDescriptor_6c07b07c062484ab, []int{194} } func (m *SecretReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5484,7 +5512,7 @@ var xxx_messageInfo_SecretReference proto.InternalMessageInfo func (m *SecretVolumeSource) Reset() { *m = SecretVolumeSource{} } func (*SecretVolumeSource) ProtoMessage() {} func (*SecretVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{194} + return fileDescriptor_6c07b07c062484ab, []int{195} } func (m *SecretVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5512,7 +5540,7 @@ var xxx_messageInfo_SecretVolumeSource proto.InternalMessageInfo func (m *SecurityContext) Reset() { *m = SecurityContext{} } func (*SecurityContext) ProtoMessage() {} func (*SecurityContext) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{195} + return fileDescriptor_6c07b07c062484ab, []int{196} } func (m *SecurityContext) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5540,7 +5568,7 @@ var xxx_messageInfo_SecurityContext proto.InternalMessageInfo func (m *SerializedReference) Reset() { *m = SerializedReference{} } func (*SerializedReference) ProtoMessage() {} func (*SerializedReference) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{196} + return fileDescriptor_6c07b07c062484ab, []int{197} } func (m *SerializedReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5568,7 +5596,7 @@ var xxx_messageInfo_SerializedReference proto.InternalMessageInfo func (m *Service) Reset() { *m = Service{} } func (*Service) ProtoMessage() {} func (*Service) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{197} + return fileDescriptor_6c07b07c062484ab, []int{198} } func (m *Service) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5596,7 +5624,7 @@ var xxx_messageInfo_Service proto.InternalMessageInfo func (m *ServiceAccount) Reset() { *m = ServiceAccount{} } func (*ServiceAccount) ProtoMessage() {} func (*ServiceAccount) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{198} + return fileDescriptor_6c07b07c062484ab, []int{199} } func (m *ServiceAccount) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5624,7 +5652,7 @@ var xxx_messageInfo_ServiceAccount proto.InternalMessageInfo func (m *ServiceAccountList) Reset() { *m = ServiceAccountList{} } func (*ServiceAccountList) ProtoMessage() {} func (*ServiceAccountList) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{199} + return fileDescriptor_6c07b07c062484ab, []int{200} } func (m *ServiceAccountList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5652,7 +5680,7 @@ var xxx_messageInfo_ServiceAccountList proto.InternalMessageInfo func (m *ServiceAccountTokenProjection) Reset() { *m = ServiceAccountTokenProjection{} } func (*ServiceAccountTokenProjection) ProtoMessage() {} func (*ServiceAccountTokenProjection) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{200} + return fileDescriptor_6c07b07c062484ab, []int{201} } func (m *ServiceAccountTokenProjection) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5680,7 +5708,7 @@ var xxx_messageInfo_ServiceAccountTokenProjection proto.InternalMessageInfo func (m *ServiceList) Reset() { *m = ServiceList{} } func (*ServiceList) ProtoMessage() {} func (*ServiceList) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{201} + return fileDescriptor_6c07b07c062484ab, []int{202} } func (m *ServiceList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5708,7 +5736,7 @@ var xxx_messageInfo_ServiceList proto.InternalMessageInfo func (m *ServicePort) Reset() { *m = ServicePort{} } func (*ServicePort) ProtoMessage() {} func (*ServicePort) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{202} + return fileDescriptor_6c07b07c062484ab, []int{203} } func (m *ServicePort) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5736,7 +5764,7 @@ var xxx_messageInfo_ServicePort proto.InternalMessageInfo func (m *ServiceProxyOptions) Reset() { *m = ServiceProxyOptions{} } func (*ServiceProxyOptions) ProtoMessage() {} func (*ServiceProxyOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{203} + return fileDescriptor_6c07b07c062484ab, []int{204} } func (m *ServiceProxyOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5764,7 +5792,7 @@ var xxx_messageInfo_ServiceProxyOptions proto.InternalMessageInfo func (m *ServiceSpec) Reset() { *m = ServiceSpec{} } func (*ServiceSpec) ProtoMessage() {} func (*ServiceSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{204} + return fileDescriptor_6c07b07c062484ab, []int{205} } func (m *ServiceSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5792,7 +5820,7 @@ var xxx_messageInfo_ServiceSpec proto.InternalMessageInfo func (m *ServiceStatus) Reset() { *m = ServiceStatus{} } func (*ServiceStatus) ProtoMessage() {} func (*ServiceStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{205} + return fileDescriptor_6c07b07c062484ab, []int{206} } func (m *ServiceStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5820,7 +5848,7 @@ var xxx_messageInfo_ServiceStatus proto.InternalMessageInfo func (m *SessionAffinityConfig) Reset() { *m = SessionAffinityConfig{} } func (*SessionAffinityConfig) ProtoMessage() {} func (*SessionAffinityConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{206} + return fileDescriptor_6c07b07c062484ab, []int{207} } func (m *SessionAffinityConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5848,7 +5876,7 @@ var xxx_messageInfo_SessionAffinityConfig proto.InternalMessageInfo func (m *SleepAction) Reset() { *m = SleepAction{} } func (*SleepAction) ProtoMessage() {} func (*SleepAction) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{207} + return fileDescriptor_6c07b07c062484ab, []int{208} } func (m *SleepAction) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5876,7 +5904,7 @@ var xxx_messageInfo_SleepAction proto.InternalMessageInfo func (m *StorageOSPersistentVolumeSource) Reset() { *m = StorageOSPersistentVolumeSource{} } func (*StorageOSPersistentVolumeSource) ProtoMessage() {} func (*StorageOSPersistentVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{208} + return fileDescriptor_6c07b07c062484ab, []int{209} } func (m *StorageOSPersistentVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5904,7 +5932,7 @@ var xxx_messageInfo_StorageOSPersistentVolumeSource proto.InternalMessageInfo func (m *StorageOSVolumeSource) Reset() { *m = StorageOSVolumeSource{} } func (*StorageOSVolumeSource) ProtoMessage() {} func (*StorageOSVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{209} + return fileDescriptor_6c07b07c062484ab, []int{210} } func (m *StorageOSVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5932,7 +5960,7 @@ var xxx_messageInfo_StorageOSVolumeSource proto.InternalMessageInfo func (m *Sysctl) Reset() { *m = Sysctl{} } func (*Sysctl) ProtoMessage() {} func (*Sysctl) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{210} + return fileDescriptor_6c07b07c062484ab, []int{211} } func (m *Sysctl) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5960,7 +5988,7 @@ var xxx_messageInfo_Sysctl proto.InternalMessageInfo func (m *TCPSocketAction) Reset() { *m = TCPSocketAction{} } func (*TCPSocketAction) ProtoMessage() {} func (*TCPSocketAction) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{211} + return fileDescriptor_6c07b07c062484ab, []int{212} } func (m *TCPSocketAction) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -5988,7 +6016,7 @@ var xxx_messageInfo_TCPSocketAction proto.InternalMessageInfo func (m *Taint) Reset() { *m = Taint{} } func (*Taint) ProtoMessage() {} func (*Taint) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{212} + return fileDescriptor_6c07b07c062484ab, []int{213} } func (m *Taint) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6016,7 +6044,7 @@ var xxx_messageInfo_Taint proto.InternalMessageInfo func (m *Toleration) Reset() { *m = Toleration{} } func (*Toleration) ProtoMessage() {} func (*Toleration) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{213} + return fileDescriptor_6c07b07c062484ab, []int{214} } func (m *Toleration) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6044,7 +6072,7 @@ var xxx_messageInfo_Toleration proto.InternalMessageInfo func (m *TopologySelectorLabelRequirement) Reset() { *m = TopologySelectorLabelRequirement{} } func (*TopologySelectorLabelRequirement) ProtoMessage() {} func (*TopologySelectorLabelRequirement) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{214} + return fileDescriptor_6c07b07c062484ab, []int{215} } func (m *TopologySelectorLabelRequirement) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6072,7 +6100,7 @@ var xxx_messageInfo_TopologySelectorLabelRequirement proto.InternalMessageInfo func (m *TopologySelectorTerm) Reset() { *m = TopologySelectorTerm{} } func (*TopologySelectorTerm) ProtoMessage() {} func (*TopologySelectorTerm) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{215} + return fileDescriptor_6c07b07c062484ab, []int{216} } func (m *TopologySelectorTerm) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6100,7 +6128,7 @@ var xxx_messageInfo_TopologySelectorTerm proto.InternalMessageInfo func (m *TopologySpreadConstraint) Reset() { *m = TopologySpreadConstraint{} } func (*TopologySpreadConstraint) ProtoMessage() {} func (*TopologySpreadConstraint) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{216} + return fileDescriptor_6c07b07c062484ab, []int{217} } func (m *TopologySpreadConstraint) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6128,7 +6156,7 @@ var xxx_messageInfo_TopologySpreadConstraint proto.InternalMessageInfo func (m *TypedLocalObjectReference) Reset() { *m = TypedLocalObjectReference{} } func (*TypedLocalObjectReference) ProtoMessage() {} func (*TypedLocalObjectReference) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{217} + return fileDescriptor_6c07b07c062484ab, []int{218} } func (m *TypedLocalObjectReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6156,7 +6184,7 @@ var xxx_messageInfo_TypedLocalObjectReference proto.InternalMessageInfo func (m *TypedObjectReference) Reset() { *m = TypedObjectReference{} } func (*TypedObjectReference) ProtoMessage() {} func (*TypedObjectReference) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{218} + return fileDescriptor_6c07b07c062484ab, []int{219} } func (m *TypedObjectReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6184,7 +6212,7 @@ var xxx_messageInfo_TypedObjectReference proto.InternalMessageInfo func (m *Volume) Reset() { *m = Volume{} } func (*Volume) ProtoMessage() {} func (*Volume) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{219} + return fileDescriptor_6c07b07c062484ab, []int{220} } func (m *Volume) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6212,7 +6240,7 @@ var xxx_messageInfo_Volume proto.InternalMessageInfo func (m *VolumeDevice) Reset() { *m = VolumeDevice{} } func (*VolumeDevice) ProtoMessage() {} func (*VolumeDevice) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{220} + return fileDescriptor_6c07b07c062484ab, []int{221} } func (m *VolumeDevice) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6240,7 +6268,7 @@ var xxx_messageInfo_VolumeDevice proto.InternalMessageInfo func (m *VolumeMount) Reset() { *m = VolumeMount{} } func (*VolumeMount) ProtoMessage() {} func (*VolumeMount) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{221} + return fileDescriptor_6c07b07c062484ab, []int{222} } func (m *VolumeMount) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6268,7 +6296,7 @@ var xxx_messageInfo_VolumeMount proto.InternalMessageInfo func (m *VolumeMountStatus) Reset() { *m = VolumeMountStatus{} } func (*VolumeMountStatus) ProtoMessage() {} func (*VolumeMountStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{222} + return fileDescriptor_6c07b07c062484ab, []int{223} } func (m *VolumeMountStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6296,7 +6324,7 @@ var xxx_messageInfo_VolumeMountStatus proto.InternalMessageInfo func (m *VolumeNodeAffinity) Reset() { *m = VolumeNodeAffinity{} } func (*VolumeNodeAffinity) ProtoMessage() {} func (*VolumeNodeAffinity) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{223} + return fileDescriptor_6c07b07c062484ab, []int{224} } func (m *VolumeNodeAffinity) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6324,7 +6352,7 @@ var xxx_messageInfo_VolumeNodeAffinity proto.InternalMessageInfo func (m *VolumeProjection) Reset() { *m = VolumeProjection{} } func (*VolumeProjection) ProtoMessage() {} func (*VolumeProjection) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{224} + return fileDescriptor_6c07b07c062484ab, []int{225} } func (m *VolumeProjection) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6352,7 +6380,7 @@ var xxx_messageInfo_VolumeProjection proto.InternalMessageInfo func (m *VolumeResourceRequirements) Reset() { *m = VolumeResourceRequirements{} } func (*VolumeResourceRequirements) ProtoMessage() {} func (*VolumeResourceRequirements) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{225} + return fileDescriptor_6c07b07c062484ab, []int{226} } func (m *VolumeResourceRequirements) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6380,7 +6408,7 @@ var xxx_messageInfo_VolumeResourceRequirements proto.InternalMessageInfo func (m *VolumeSource) Reset() { *m = VolumeSource{} } func (*VolumeSource) ProtoMessage() {} func (*VolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{226} + return fileDescriptor_6c07b07c062484ab, []int{227} } func (m *VolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6408,7 +6436,7 @@ var xxx_messageInfo_VolumeSource proto.InternalMessageInfo func (m *VsphereVirtualDiskVolumeSource) Reset() { *m = VsphereVirtualDiskVolumeSource{} } func (*VsphereVirtualDiskVolumeSource) ProtoMessage() {} func (*VsphereVirtualDiskVolumeSource) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{227} + return fileDescriptor_6c07b07c062484ab, []int{228} } func (m *VsphereVirtualDiskVolumeSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6436,7 +6464,7 @@ var xxx_messageInfo_VsphereVirtualDiskVolumeSource proto.InternalMessageInfo func (m *WeightedPodAffinityTerm) Reset() { *m = WeightedPodAffinityTerm{} } func (*WeightedPodAffinityTerm) ProtoMessage() {} func (*WeightedPodAffinityTerm) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{228} + return fileDescriptor_6c07b07c062484ab, []int{229} } func (m *WeightedPodAffinityTerm) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6464,7 +6492,7 @@ var xxx_messageInfo_WeightedPodAffinityTerm proto.InternalMessageInfo func (m *WindowsSecurityContextOptions) Reset() { *m = WindowsSecurityContextOptions{} } func (*WindowsSecurityContextOptions) ProtoMessage() {} func (*WindowsSecurityContextOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_6c07b07c062484ab, []int{229} + return fileDescriptor_6c07b07c062484ab, []int{230} } func (m *WindowsSecurityContextOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -6617,6 +6645,7 @@ func init() { proto.RegisterType((*NodeStatus)(nil), "k8s.io.api.core.v1.NodeStatus") proto.RegisterMapType((ResourceList)(nil), "k8s.io.api.core.v1.NodeStatus.AllocatableEntry") proto.RegisterMapType((ResourceList)(nil), "k8s.io.api.core.v1.NodeStatus.CapacityEntry") + proto.RegisterType((*NodeSwapStatus)(nil), "k8s.io.api.core.v1.NodeSwapStatus") proto.RegisterType((*NodeSystemInfo)(nil), "k8s.io.api.core.v1.NodeSystemInfo") proto.RegisterType((*ObjectFieldSelector)(nil), "k8s.io.api.core.v1.ObjectFieldSelector") proto.RegisterType((*ObjectReference)(nil), "k8s.io.api.core.v1.ObjectReference") @@ -6758,1015 +6787,1020 @@ func init() { } var fileDescriptor_6c07b07c062484ab = []byte{ - // 16114 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xbd, 0x69, 0x90, 0x64, 0xd9, - 0x59, 0x28, 0xa6, 0x9b, 0x59, 0xeb, 0x57, 0xfb, 0xa9, 0x5e, 0xaa, 0x6b, 0xba, 0x3b, 0x7b, 0xee, - 0xcc, 0xf4, 0xf4, 0x6c, 0xd5, 0xea, 0x59, 0x34, 0xad, 0x99, 0xd1, 0x30, 0xb5, 0x76, 0xd7, 0x74, - 0x57, 0x75, 0xce, 0xc9, 0xaa, 0x6e, 0x69, 0x34, 0x12, 0xba, 0x9d, 0x79, 0xaa, 0xea, 0xaa, 0x32, - 0xef, 0xcd, 0xb9, 0xf7, 0x66, 0x75, 0x57, 0x5b, 0x04, 0x20, 0x8c, 0x40, 0x02, 0x47, 0x28, 0x08, - 0x6c, 0x1c, 0x82, 0xe0, 0x07, 0x60, 0x16, 0xcb, 0x60, 0x64, 0x61, 0xc0, 0x88, 0xcd, 0x36, 0x8e, - 0x00, 0xff, 0xc0, 0x98, 0x08, 0x4b, 0x84, 0x09, 0x17, 0x56, 0xe1, 0x08, 0x82, 0x1f, 0x06, 0x82, - 0xf7, 0x7e, 0xbc, 0x57, 0xc1, 0x7b, 0xbc, 0x38, 0xeb, 0x3d, 0xe7, 0x2e, 0x99, 0x59, 0x3d, 0xdd, - 0xa5, 0x91, 0x62, 0xfe, 0x65, 0x9e, 0xef, 0x3b, 0xdf, 0x39, 0xf7, 0xac, 0xdf, 0xf9, 0x56, 0xb0, - 0xb7, 0x2f, 0x87, 0x33, 0xae, 0x7f, 0xd1, 0x69, 0xba, 0x17, 0xab, 0x7e, 0x40, 0x2e, 0xee, 0x5c, - 0xba, 0xb8, 0x49, 0x3c, 0x12, 0x38, 0x11, 0xa9, 0xcd, 0x34, 0x03, 0x3f, 0xf2, 0x11, 0xe2, 0x38, - 0x33, 0x4e, 0xd3, 0x9d, 0xa1, 0x38, 0x33, 0x3b, 0x97, 0xa6, 0x9f, 0xdb, 0x74, 0xa3, 0xad, 0xd6, - 0xed, 0x99, 0xaa, 0xdf, 0xb8, 0xb8, 0xe9, 0x6f, 0xfa, 0x17, 0x19, 0xea, 0xed, 0xd6, 0x06, 0xfb, - 0xc7, 0xfe, 0xb0, 0x5f, 0x9c, 0xc4, 0xf4, 0x8b, 0x71, 0x33, 0x0d, 0xa7, 0xba, 0xe5, 0x7a, 0x24, - 0xd8, 0xbd, 0xd8, 0xdc, 0xde, 0x64, 0xed, 0x06, 0x24, 0xf4, 0x5b, 0x41, 0x95, 0x24, 0x1b, 0x6e, - 0x5b, 0x2b, 0xbc, 0xd8, 0x20, 0x91, 0x93, 0xd1, 0xdd, 0xe9, 0x8b, 0x79, 0xb5, 0x82, 0x96, 0x17, - 0xb9, 0x8d, 0x74, 0x33, 0x1f, 0xe9, 0x54, 0x21, 0xac, 0x6e, 0x91, 0x86, 0x93, 0xaa, 0xf7, 0x42, - 0x5e, 0xbd, 0x56, 0xe4, 0xd6, 0x2f, 0xba, 0x5e, 0x14, 0x46, 0x41, 0xb2, 0x92, 0xfd, 0x2d, 0x0b, - 0xce, 0xcd, 0xde, 0xaa, 0x2c, 0xd6, 0x9d, 0x30, 0x72, 0xab, 0x73, 0x75, 0xbf, 0xba, 0x5d, 0x89, - 0xfc, 0x80, 0xdc, 0xf4, 0xeb, 0xad, 0x06, 0xa9, 0xb0, 0x81, 0x40, 0xcf, 0xc2, 0xc0, 0x0e, 0xfb, - 0xbf, 0xbc, 0x30, 0x65, 0x9d, 0xb3, 0x2e, 0x0c, 0xce, 0x8d, 0xff, 0xe9, 0x5e, 0xe9, 0x43, 0xfb, - 0x7b, 0xa5, 0x81, 0x9b, 0xa2, 0x1c, 0x2b, 0x0c, 0x74, 0x1e, 0xfa, 0x36, 0xc2, 0xb5, 0xdd, 0x26, - 0x99, 0x2a, 0x30, 0xdc, 0x51, 0x81, 0xdb, 0xb7, 0x54, 0xa1, 0xa5, 0x58, 0x40, 0xd1, 0x45, 0x18, - 0x6c, 0x3a, 0x41, 0xe4, 0x46, 0xae, 0xef, 0x4d, 0x15, 0xcf, 0x59, 0x17, 0x7a, 0xe7, 0x26, 0x04, - 0xea, 0x60, 0x59, 0x02, 0x70, 0x8c, 0x43, 0xbb, 0x11, 0x10, 0xa7, 0x76, 0xc3, 0xab, 0xef, 0x4e, - 0xf5, 0x9c, 0xb3, 0x2e, 0x0c, 0xc4, 0xdd, 0xc0, 0xa2, 0x1c, 0x2b, 0x0c, 0xfb, 0x2b, 0x05, 0x18, - 0x98, 0xdd, 0xd8, 0x70, 0x3d, 0x37, 0xda, 0x45, 0x37, 0x61, 0xd8, 0xf3, 0x6b, 0x44, 0xfe, 0x67, - 0x5f, 0x31, 0xf4, 0xfc, 0xb9, 0x99, 0xf4, 0x52, 0x9a, 0x59, 0xd5, 0xf0, 0xe6, 0xc6, 0xf7, 0xf7, - 0x4a, 0xc3, 0x7a, 0x09, 0x36, 0xe8, 0x20, 0x0c, 0x43, 0x4d, 0xbf, 0xa6, 0xc8, 0x16, 0x18, 0xd9, - 0x52, 0x16, 0xd9, 0x72, 0x8c, 0x36, 0x37, 0xb6, 0xbf, 0x57, 0x1a, 0xd2, 0x0a, 0xb0, 0x4e, 0x04, - 0xdd, 0x86, 0x31, 0xfa, 0xd7, 0x8b, 0x5c, 0x45, 0xb7, 0xc8, 0xe8, 0x3e, 0x96, 0x47, 0x57, 0x43, - 0x9d, 0x9b, 0xdc, 0xdf, 0x2b, 0x8d, 0x25, 0x0a, 0x71, 0x92, 0xa0, 0xfd, 0x93, 0x16, 0x8c, 0xcd, - 0x36, 0x9b, 0xb3, 0x41, 0xc3, 0x0f, 0xca, 0x81, 0xbf, 0xe1, 0xd6, 0x09, 0x7a, 0x19, 0x7a, 0x22, - 0x3a, 0x6b, 0x7c, 0x86, 0x1f, 0x13, 0x43, 0xdb, 0x43, 0xe7, 0xea, 0x60, 0xaf, 0x34, 0x99, 0x40, - 0x67, 0x53, 0xc9, 0x2a, 0xa0, 0x37, 0x60, 0xbc, 0xee, 0x57, 0x9d, 0xfa, 0x96, 0x1f, 0x46, 0x02, - 0x2a, 0xa6, 0xfe, 0xd8, 0xfe, 0x5e, 0x69, 0xfc, 0x7a, 0x02, 0x86, 0x53, 0xd8, 0xf6, 0x3d, 0x18, - 0x9d, 0x8d, 0x22, 0xa7, 0xba, 0x45, 0x6a, 0x7c, 0x41, 0xa1, 0x17, 0xa1, 0xc7, 0x73, 0x1a, 0xb2, - 0x33, 0xe7, 0x64, 0x67, 0x56, 0x9d, 0x06, 0xed, 0xcc, 0xf8, 0xba, 0xe7, 0xbe, 0xdb, 0x12, 0x8b, - 0x94, 0x96, 0x61, 0x86, 0x8d, 0x9e, 0x07, 0xa8, 0x91, 0x1d, 0xb7, 0x4a, 0xca, 0x4e, 0xb4, 0x25, - 0xfa, 0x80, 0x44, 0x5d, 0x58, 0x50, 0x10, 0xac, 0x61, 0xd9, 0x77, 0x61, 0x70, 0x76, 0xc7, 0x77, - 0x6b, 0x65, 0xbf, 0x16, 0xa2, 0x6d, 0x18, 0x6b, 0x06, 0x64, 0x83, 0x04, 0xaa, 0x68, 0xca, 0x3a, - 0x57, 0xbc, 0x30, 0xf4, 0xfc, 0x85, 0xcc, 0xb1, 0x37, 0x51, 0x17, 0xbd, 0x28, 0xd8, 0x9d, 0x3b, - 0x29, 0xda, 0x1b, 0x4b, 0x40, 0x71, 0x92, 0xb2, 0xfd, 0x27, 0x05, 0x38, 0x3e, 0x7b, 0xaf, 0x15, - 0x90, 0x05, 0x37, 0xdc, 0x4e, 0x6e, 0xb8, 0x9a, 0x1b, 0x6e, 0xaf, 0xc6, 0x23, 0xa0, 0x56, 0xfa, - 0x82, 0x28, 0xc7, 0x0a, 0x03, 0x3d, 0x07, 0xfd, 0xf4, 0xf7, 0x3a, 0x5e, 0x16, 0x9f, 0x3c, 0x29, - 0x90, 0x87, 0x16, 0x9c, 0xc8, 0x59, 0xe0, 0x20, 0x2c, 0x71, 0xd0, 0x0a, 0x0c, 0x55, 0xd9, 0xf9, - 0xb0, 0xb9, 0xe2, 0xd7, 0x08, 0x5b, 0x5b, 0x83, 0x73, 0xcf, 0x50, 0xf4, 0xf9, 0xb8, 0xf8, 0x60, - 0xaf, 0x34, 0xc5, 0xfb, 0x26, 0x48, 0x68, 0x30, 0xac, 0xd7, 0x47, 0xb6, 0xda, 0xee, 0x3d, 0x8c, - 0x12, 0x64, 0x6c, 0xf5, 0x0b, 0xda, 0xce, 0xed, 0x65, 0x3b, 0x77, 0x38, 0x7b, 0xd7, 0xa2, 0x4b, - 0xd0, 0xb3, 0xed, 0x7a, 0xb5, 0xa9, 0x3e, 0x46, 0xeb, 0x0c, 0x9d, 0xf3, 0x6b, 0xae, 0x57, 0x3b, - 0xd8, 0x2b, 0x4d, 0x18, 0xdd, 0xa1, 0x85, 0x98, 0xa1, 0xda, 0xff, 0xc6, 0x82, 0x12, 0x83, 0x2d, - 0xb9, 0x75, 0x52, 0x26, 0x41, 0xe8, 0x86, 0x11, 0xf1, 0x22, 0x63, 0x40, 0x9f, 0x07, 0x08, 0x49, - 0x35, 0x20, 0x91, 0x36, 0xa4, 0x6a, 0x61, 0x54, 0x14, 0x04, 0x6b, 0x58, 0xf4, 0x7c, 0x0a, 0xb7, - 0x9c, 0x80, 0xad, 0x2f, 0x31, 0xb0, 0xea, 0x7c, 0xaa, 0x48, 0x00, 0x8e, 0x71, 0x8c, 0xf3, 0xa9, - 0xd8, 0xe9, 0x7c, 0x42, 0x1f, 0x83, 0xb1, 0xb8, 0xb1, 0xb0, 0xe9, 0x54, 0xe5, 0x00, 0xb2, 0x1d, - 0x5c, 0x31, 0x41, 0x38, 0x89, 0x6b, 0xff, 0xb7, 0x96, 0x58, 0x3c, 0xf4, 0xab, 0xdf, 0xe7, 0xdf, - 0x6a, 0xff, 0xae, 0x05, 0xfd, 0x73, 0xae, 0x57, 0x73, 0xbd, 0x4d, 0xf4, 0x19, 0x18, 0xa0, 0x57, - 0x65, 0xcd, 0x89, 0x1c, 0x71, 0x0c, 0x7f, 0x58, 0xdb, 0x5b, 0xea, 0xe6, 0x9a, 0x69, 0x6e, 0x6f, - 0xd2, 0x82, 0x70, 0x86, 0x62, 0xd3, 0xdd, 0x76, 0xe3, 0xf6, 0x67, 0x49, 0x35, 0x5a, 0x21, 0x91, - 0x13, 0x7f, 0x4e, 0x5c, 0x86, 0x15, 0x55, 0x74, 0x0d, 0xfa, 0x22, 0x27, 0xd8, 0x24, 0x91, 0x38, - 0x8f, 0x33, 0xcf, 0x4d, 0x5e, 0x13, 0xd3, 0x1d, 0x49, 0xbc, 0x2a, 0x89, 0x6f, 0xa9, 0x35, 0x56, - 0x15, 0x0b, 0x12, 0xf6, 0x7f, 0xe8, 0x87, 0x53, 0xf3, 0x95, 0xe5, 0x9c, 0x75, 0x75, 0x1e, 0xfa, - 0x6a, 0x81, 0xbb, 0x43, 0x02, 0x31, 0xce, 0x8a, 0xca, 0x02, 0x2b, 0xc5, 0x02, 0x8a, 0x2e, 0xc3, - 0x30, 0xbf, 0x1f, 0xaf, 0x3a, 0x5e, 0x2d, 0x3e, 0x1e, 0x05, 0xf6, 0xf0, 0x4d, 0x0d, 0x86, 0x0d, - 0xcc, 0x43, 0x2e, 0xaa, 0xf3, 0x89, 0xcd, 0x98, 0x77, 0xf7, 0x7e, 0xd1, 0x82, 0x71, 0xde, 0xcc, - 0x6c, 0x14, 0x05, 0xee, 0xed, 0x56, 0x44, 0xc2, 0xa9, 0x5e, 0x76, 0xd2, 0xcd, 0x67, 0x8d, 0x56, - 0xee, 0x08, 0xcc, 0xdc, 0x4c, 0x50, 0xe1, 0x87, 0xe0, 0x94, 0x68, 0x77, 0x3c, 0x09, 0xc6, 0xa9, - 0x66, 0xd1, 0x8f, 0x58, 0x30, 0x5d, 0xf5, 0xbd, 0x28, 0xf0, 0xeb, 0x75, 0x12, 0x94, 0x5b, 0xb7, - 0xeb, 0x6e, 0xb8, 0xc5, 0xd7, 0x29, 0x26, 0x1b, 0xec, 0x24, 0xc8, 0x99, 0x43, 0x85, 0x24, 0xe6, - 0xf0, 0xec, 0xfe, 0x5e, 0x69, 0x7a, 0x3e, 0x97, 0x14, 0x6e, 0xd3, 0x0c, 0xda, 0x06, 0x44, 0x6f, - 0xf6, 0x4a, 0xe4, 0x6c, 0x92, 0xb8, 0xf1, 0xfe, 0xee, 0x1b, 0x3f, 0xb1, 0xbf, 0x57, 0x42, 0xab, - 0x29, 0x12, 0x38, 0x83, 0x2c, 0x7a, 0x17, 0x8e, 0xd1, 0xd2, 0xd4, 0xb7, 0x0e, 0x74, 0xdf, 0xdc, - 0xd4, 0xfe, 0x5e, 0xe9, 0xd8, 0x6a, 0x06, 0x11, 0x9c, 0x49, 0x1a, 0xfd, 0x90, 0x05, 0xa7, 0xe2, - 0xcf, 0x5f, 0xbc, 0xdb, 0x74, 0xbc, 0x5a, 0xdc, 0xf0, 0x60, 0xf7, 0x0d, 0xd3, 0x33, 0xf9, 0xd4, - 0x7c, 0x1e, 0x25, 0x9c, 0xdf, 0x08, 0xf2, 0x60, 0x92, 0x76, 0x2d, 0xd9, 0x36, 0x74, 0xdf, 0xf6, - 0xc9, 0xfd, 0xbd, 0xd2, 0xe4, 0x6a, 0x9a, 0x06, 0xce, 0x22, 0x3c, 0x3d, 0x0f, 0xc7, 0x33, 0x57, - 0x27, 0x1a, 0x87, 0xe2, 0x36, 0xe1, 0x4c, 0xe0, 0x20, 0xa6, 0x3f, 0xd1, 0x31, 0xe8, 0xdd, 0x71, - 0xea, 0x2d, 0xb1, 0x31, 0x31, 0xff, 0xf3, 0x4a, 0xe1, 0xb2, 0x65, 0xff, 0x6f, 0x45, 0x18, 0x9b, - 0xaf, 0x2c, 0xdf, 0xd7, 0xae, 0xd7, 0xaf, 0xbd, 0x42, 0xdb, 0x6b, 0x2f, 0xbe, 0x44, 0x8b, 0xb9, - 0x97, 0xe8, 0x0f, 0x66, 0x6c, 0xd9, 0x1e, 0xb6, 0x65, 0x3f, 0x9a, 0xb3, 0x65, 0x1f, 0xf0, 0x46, - 0xdd, 0xc9, 0x59, 0xb5, 0xbd, 0x6c, 0x02, 0x33, 0x39, 0x24, 0xc6, 0xfb, 0x25, 0x8f, 0xda, 0x43, - 0x2e, 0xdd, 0x07, 0x33, 0x8f, 0x55, 0x18, 0x9e, 0x77, 0x9a, 0xce, 0x6d, 0xb7, 0xee, 0x46, 0x2e, - 0x09, 0xd1, 0x93, 0x50, 0x74, 0x6a, 0x35, 0xc6, 0xdd, 0x0d, 0xce, 0x1d, 0xdf, 0xdf, 0x2b, 0x15, - 0x67, 0x6b, 0x94, 0xcd, 0x00, 0x85, 0xb5, 0x8b, 0x29, 0x06, 0x7a, 0x1a, 0x7a, 0x6a, 0x81, 0xdf, - 0x9c, 0x2a, 0x30, 0x4c, 0xba, 0xcb, 0x7b, 0x16, 0x02, 0xbf, 0x99, 0x40, 0x65, 0x38, 0xf6, 0x1f, - 0x17, 0xe0, 0xf4, 0x3c, 0x69, 0x6e, 0x2d, 0x55, 0x72, 0xee, 0x8b, 0x0b, 0x30, 0xd0, 0xf0, 0x3d, - 0x37, 0xf2, 0x83, 0x50, 0x34, 0xcd, 0x56, 0xc4, 0x8a, 0x28, 0xc3, 0x0a, 0x8a, 0xce, 0x41, 0x4f, - 0x33, 0x66, 0x62, 0x87, 0x25, 0x03, 0xcc, 0xd8, 0x57, 0x06, 0xa1, 0x18, 0xad, 0x90, 0x04, 0x62, - 0xc5, 0x28, 0x8c, 0xf5, 0x90, 0x04, 0x98, 0x41, 0x62, 0x4e, 0x80, 0xf2, 0x08, 0xe2, 0x46, 0x48, - 0x70, 0x02, 0x14, 0x82, 0x35, 0x2c, 0x54, 0x86, 0xc1, 0x30, 0x31, 0xb3, 0x5d, 0x6d, 0xcd, 0x11, - 0xc6, 0x2a, 0xa8, 0x99, 0x8c, 0x89, 0x18, 0x37, 0x58, 0x5f, 0x47, 0x56, 0xe1, 0x1b, 0x05, 0x40, - 0x7c, 0x08, 0xbf, 0xcb, 0x06, 0x6e, 0x3d, 0x3d, 0x70, 0xdd, 0x6f, 0x89, 0x07, 0x35, 0x7a, 0xff, - 0xd6, 0x82, 0xd3, 0xf3, 0xae, 0x57, 0x23, 0x41, 0xce, 0x02, 0x7c, 0x38, 0x4f, 0xf9, 0xc3, 0x31, - 0x29, 0xc6, 0x12, 0xeb, 0x79, 0x00, 0x4b, 0xcc, 0xfe, 0x47, 0x0b, 0x10, 0xff, 0xec, 0xf7, 0xdd, - 0xc7, 0xae, 0xa7, 0x3f, 0xf6, 0x01, 0x2c, 0x0b, 0xfb, 0x3a, 0x8c, 0xce, 0xd7, 0x5d, 0xe2, 0x45, - 0xcb, 0xe5, 0x79, 0xdf, 0xdb, 0x70, 0x37, 0xd1, 0x2b, 0x30, 0x1a, 0xb9, 0x0d, 0xe2, 0xb7, 0xa2, - 0x0a, 0xa9, 0xfa, 0x1e, 0x7b, 0xb9, 0x5a, 0x17, 0x7a, 0xe7, 0xd0, 0xfe, 0x5e, 0x69, 0x74, 0xcd, - 0x80, 0xe0, 0x04, 0xa6, 0xfd, 0xcb, 0xf4, 0xdc, 0xaa, 0xb7, 0xc2, 0x88, 0x04, 0x6b, 0x41, 0x2b, - 0x8c, 0xe6, 0x5a, 0x94, 0xf7, 0x2c, 0x07, 0x3e, 0xed, 0x8e, 0xeb, 0x7b, 0xe8, 0xb4, 0xf1, 0x1c, - 0x1f, 0x90, 0x4f, 0x71, 0xf1, 0xec, 0x9e, 0x01, 0x08, 0xdd, 0x4d, 0x8f, 0x04, 0xda, 0xf3, 0x61, - 0x94, 0x6d, 0x15, 0x55, 0x8a, 0x35, 0x0c, 0x54, 0x87, 0x91, 0xba, 0x73, 0x9b, 0xd4, 0x2b, 0xa4, - 0x4e, 0xaa, 0x91, 0x1f, 0x08, 0xf9, 0xc6, 0x0b, 0xdd, 0xbd, 0x03, 0xae, 0xeb, 0x55, 0xe7, 0x26, - 0xf6, 0xf7, 0x4a, 0x23, 0x46, 0x11, 0x36, 0x89, 0xd3, 0xa3, 0xc3, 0x6f, 0xd2, 0xaf, 0x70, 0xea, - 0xfa, 0xe3, 0xf3, 0x86, 0x28, 0xc3, 0x0a, 0xaa, 0x8e, 0x8e, 0x9e, 0xbc, 0xa3, 0xc3, 0xfe, 0x6b, - 0xba, 0xd0, 0xfc, 0x46, 0xd3, 0xf7, 0x88, 0x17, 0xcd, 0xfb, 0x5e, 0x8d, 0x4b, 0xa6, 0x5e, 0x31, - 0x44, 0x27, 0xe7, 0x13, 0xa2, 0x93, 0x13, 0xe9, 0x1a, 0x9a, 0xf4, 0xe4, 0xa3, 0xd0, 0x17, 0x46, - 0x4e, 0xd4, 0x0a, 0xc5, 0xc0, 0x3d, 0x2a, 0x97, 0x5d, 0x85, 0x95, 0x1e, 0xec, 0x95, 0xc6, 0x54, - 0x35, 0x5e, 0x84, 0x45, 0x05, 0xf4, 0x14, 0xf4, 0x37, 0x48, 0x18, 0x3a, 0x9b, 0x92, 0x6d, 0x18, - 0x13, 0x75, 0xfb, 0x57, 0x78, 0x31, 0x96, 0x70, 0xf4, 0x18, 0xf4, 0x92, 0x20, 0xf0, 0x03, 0xf1, - 0x6d, 0x23, 0x02, 0xb1, 0x77, 0x91, 0x16, 0x62, 0x0e, 0xb3, 0xff, 0x0f, 0x0b, 0xc6, 0x54, 0x5f, - 0x79, 0x5b, 0x47, 0xf0, 0x5c, 0x7b, 0x1b, 0xa0, 0x2a, 0x3f, 0x30, 0x64, 0xd7, 0xec, 0xd0, 0xf3, - 0xe7, 0x33, 0x39, 0x9a, 0xd4, 0x30, 0xc6, 0x94, 0x55, 0x51, 0x88, 0x35, 0x6a, 0xf6, 0x1f, 0x58, - 0x30, 0x99, 0xf8, 0xa2, 0xeb, 0x6e, 0x18, 0xa1, 0x77, 0x52, 0x5f, 0x35, 0xd3, 0xe5, 0xe2, 0x73, - 0x43, 0xfe, 0x4d, 0x6a, 0xcf, 0xcb, 0x12, 0xed, 0x8b, 0xae, 0x42, 0xaf, 0x1b, 0x91, 0x86, 0xfc, - 0x98, 0xc7, 0xda, 0x7e, 0x0c, 0xef, 0x55, 0x3c, 0x23, 0xcb, 0xb4, 0x26, 0xe6, 0x04, 0xec, 0x3f, - 0x2e, 0xc2, 0x20, 0xdf, 0xdf, 0x2b, 0x4e, 0xf3, 0x08, 0xe6, 0xe2, 0x19, 0x18, 0x74, 0x1b, 0x8d, - 0x56, 0xe4, 0xdc, 0x16, 0xf7, 0xde, 0x00, 0x3f, 0x83, 0x96, 0x65, 0x21, 0x8e, 0xe1, 0x68, 0x19, - 0x7a, 0x58, 0x57, 0xf8, 0x57, 0x3e, 0x99, 0xfd, 0x95, 0xa2, 0xef, 0x33, 0x0b, 0x4e, 0xe4, 0x70, - 0x96, 0x53, 0xed, 0x2b, 0x5a, 0x84, 0x19, 0x09, 0xe4, 0x00, 0xdc, 0x76, 0x3d, 0x27, 0xd8, 0xa5, - 0x65, 0x53, 0x45, 0x46, 0xf0, 0xb9, 0xf6, 0x04, 0xe7, 0x14, 0x3e, 0x27, 0xab, 0x3e, 0x2c, 0x06, - 0x60, 0x8d, 0xe8, 0xf4, 0xcb, 0x30, 0xa8, 0x90, 0x0f, 0xc3, 0x39, 0x4e, 0x7f, 0x0c, 0xc6, 0x12, - 0x6d, 0x75, 0xaa, 0x3e, 0xac, 0x33, 0x9e, 0xbf, 0xc7, 0x8e, 0x0c, 0xd1, 0xeb, 0x45, 0x6f, 0x47, - 0xdc, 0x4d, 0xf7, 0xe0, 0x58, 0x3d, 0xe3, 0xc8, 0x17, 0xf3, 0xda, 0xfd, 0x15, 0x71, 0x5a, 0x7c, - 0xf6, 0xb1, 0x2c, 0x28, 0xce, 0x6c, 0xc3, 0x38, 0x11, 0x0b, 0xed, 0x4e, 0x44, 0x7a, 0xde, 0x1d, - 0x53, 0x9d, 0xbf, 0x46, 0x76, 0xd5, 0xa1, 0xfa, 0x9d, 0xec, 0xfe, 0x19, 0x3e, 0xfa, 0xfc, 0xb8, - 0x1c, 0x12, 0x04, 0x8a, 0xd7, 0xc8, 0x2e, 0x9f, 0x0a, 0xfd, 0xeb, 0x8a, 0x6d, 0xbf, 0xee, 0x6b, - 0x16, 0x8c, 0xa8, 0xaf, 0x3b, 0x82, 0x73, 0x61, 0xce, 0x3c, 0x17, 0xce, 0xb4, 0x5d, 0xe0, 0x39, - 0x27, 0xc2, 0x37, 0x0a, 0x70, 0x4a, 0xe1, 0xd0, 0x47, 0x14, 0xff, 0x23, 0x56, 0xd5, 0x45, 0x18, - 0xf4, 0x94, 0x38, 0xd1, 0x32, 0xe5, 0x78, 0xb1, 0x30, 0x31, 0xc6, 0xa1, 0x57, 0x9e, 0x17, 0x5f, - 0xda, 0xc3, 0xba, 0x9c, 0x5d, 0x5c, 0xee, 0x73, 0x50, 0x6c, 0xb9, 0x35, 0x71, 0xc1, 0x7c, 0x58, - 0x8e, 0xf6, 0xfa, 0xf2, 0xc2, 0xc1, 0x5e, 0xe9, 0xd1, 0x3c, 0x95, 0x13, 0xbd, 0xd9, 0xc2, 0x99, - 0xf5, 0xe5, 0x05, 0x4c, 0x2b, 0xa3, 0x59, 0x18, 0x93, 0x5a, 0xb5, 0x9b, 0x94, 0x2f, 0xf5, 0x3d, - 0x71, 0x0f, 0x29, 0x61, 0x39, 0x36, 0xc1, 0x38, 0x89, 0x8f, 0x16, 0x60, 0x7c, 0xbb, 0x75, 0x9b, - 0xd4, 0x49, 0xc4, 0x3f, 0xf8, 0x1a, 0xe1, 0xa2, 0xe4, 0xc1, 0xf8, 0x09, 0x7b, 0x2d, 0x01, 0xc7, - 0xa9, 0x1a, 0xf6, 0xbf, 0xb2, 0xfb, 0x40, 0x8c, 0x9e, 0xc6, 0xdf, 0x7c, 0x27, 0x97, 0x73, 0x37, - 0xab, 0xe2, 0x1a, 0xd9, 0x5d, 0xf3, 0x29, 0x1f, 0x92, 0xbd, 0x2a, 0x8c, 0x35, 0xdf, 0xd3, 0x76, - 0xcd, 0xff, 0x56, 0x01, 0x8e, 0xab, 0x11, 0x30, 0xb8, 0xe5, 0xef, 0xf6, 0x31, 0xb8, 0x04, 0x43, - 0x35, 0xb2, 0xe1, 0xb4, 0xea, 0x91, 0xd2, 0x6b, 0xf4, 0x72, 0x55, 0xdb, 0x42, 0x5c, 0x8c, 0x75, - 0x9c, 0x43, 0x0c, 0xdb, 0xaf, 0x8f, 0xb0, 0x8b, 0x38, 0x72, 0xe8, 0x1a, 0x57, 0xbb, 0xc6, 0xca, - 0xdd, 0x35, 0x8f, 0x41, 0xaf, 0xdb, 0xa0, 0x8c, 0x59, 0xc1, 0xe4, 0xb7, 0x96, 0x69, 0x21, 0xe6, - 0x30, 0xf4, 0x04, 0xf4, 0x57, 0xfd, 0x46, 0xc3, 0xf1, 0x6a, 0xec, 0xca, 0x1b, 0x9c, 0x1b, 0xa2, - 0xbc, 0xdb, 0x3c, 0x2f, 0xc2, 0x12, 0x46, 0x99, 0x6f, 0x27, 0xd8, 0xe4, 0xc2, 0x1e, 0xc1, 0x7c, - 0xcf, 0x06, 0x9b, 0x21, 0x66, 0xa5, 0xf4, 0xad, 0x7a, 0xc7, 0x0f, 0xb6, 0x5d, 0x6f, 0x73, 0xc1, - 0x0d, 0xc4, 0x96, 0x50, 0x77, 0xe1, 0x2d, 0x05, 0xc1, 0x1a, 0x16, 0x5a, 0x82, 0xde, 0xa6, 0x1f, - 0x44, 0xe1, 0x54, 0x1f, 0x1b, 0xee, 0x47, 0x73, 0x0e, 0x22, 0xfe, 0xb5, 0x65, 0x3f, 0x88, 0xe2, - 0x0f, 0xa0, 0xff, 0x42, 0xcc, 0xab, 0xa3, 0xeb, 0xd0, 0x4f, 0xbc, 0x9d, 0xa5, 0xc0, 0x6f, 0x4c, - 0x4d, 0xe6, 0x53, 0x5a, 0xe4, 0x28, 0x7c, 0x99, 0xc5, 0x3c, 0xaa, 0x28, 0xc6, 0x92, 0x04, 0xfa, - 0x28, 0x14, 0x89, 0xb7, 0x33, 0xd5, 0xcf, 0x28, 0x4d, 0xe7, 0x50, 0xba, 0xe9, 0x04, 0xf1, 0x99, - 0xbf, 0xe8, 0xed, 0x60, 0x5a, 0x07, 0x7d, 0x02, 0x06, 0xe5, 0x81, 0x11, 0x0a, 0x29, 0x6a, 0xe6, - 0x82, 0x95, 0xc7, 0x0c, 0x26, 0xef, 0xb6, 0xdc, 0x80, 0x34, 0x88, 0x17, 0x85, 0xf1, 0x09, 0x29, - 0xa1, 0x21, 0x8e, 0xa9, 0xa1, 0x2a, 0x0c, 0x07, 0x24, 0x74, 0xef, 0x91, 0xb2, 0x5f, 0x77, 0xab, - 0xbb, 0x53, 0x27, 0x59, 0xf7, 0x9e, 0x6a, 0x3b, 0x64, 0x58, 0xab, 0x10, 0x4b, 0xf9, 0xf5, 0x52, - 0x6c, 0x10, 0x45, 0x6f, 0xc1, 0x48, 0x40, 0xc2, 0xc8, 0x09, 0x22, 0xd1, 0xca, 0x94, 0xd2, 0xca, - 0x8d, 0x60, 0x1d, 0xc0, 0x9f, 0x13, 0x71, 0x33, 0x31, 0x04, 0x9b, 0x14, 0xd0, 0x27, 0xa4, 0xca, - 0x61, 0xc5, 0x6f, 0x79, 0x51, 0x38, 0x35, 0xc8, 0xfa, 0x9d, 0xa9, 0x9b, 0xbe, 0x19, 0xe3, 0x25, - 0x75, 0x12, 0xbc, 0x32, 0x36, 0x48, 0xa1, 0x4f, 0xc1, 0x08, 0xff, 0xcf, 0x55, 0xaa, 0xe1, 0xd4, - 0x71, 0x46, 0xfb, 0x5c, 0x3e, 0x6d, 0x8e, 0x38, 0x77, 0x5c, 0x10, 0x1f, 0xd1, 0x4b, 0x43, 0x6c, - 0x52, 0x43, 0x18, 0x46, 0xea, 0xee, 0x0e, 0xf1, 0x48, 0x18, 0x96, 0x03, 0xff, 0x36, 0x11, 0x12, - 0xe2, 0x53, 0xd9, 0x2a, 0x58, 0xff, 0x36, 0x11, 0x8f, 0x40, 0xbd, 0x0e, 0x36, 0x49, 0xa0, 0x75, - 0x18, 0xa5, 0x4f, 0x72, 0x37, 0x26, 0x3a, 0xd4, 0x89, 0x28, 0x7b, 0x38, 0x63, 0xa3, 0x12, 0x4e, - 0x10, 0x41, 0x37, 0x60, 0x98, 0x8d, 0x79, 0xab, 0xc9, 0x89, 0x9e, 0xe8, 0x44, 0x94, 0x19, 0x14, - 0x54, 0xb4, 0x2a, 0xd8, 0x20, 0x80, 0xde, 0x84, 0xc1, 0xba, 0xbb, 0x41, 0xaa, 0xbb, 0xd5, 0x3a, - 0x99, 0x1a, 0x66, 0xd4, 0x32, 0x0f, 0xc3, 0xeb, 0x12, 0x89, 0xf3, 0xe7, 0xea, 0x2f, 0x8e, 0xab, - 0xa3, 0x9b, 0x70, 0x22, 0x22, 0x41, 0xc3, 0xf5, 0x1c, 0x7a, 0x88, 0x89, 0x27, 0x21, 0xd3, 0x8c, - 0x8f, 0xb0, 0xd5, 0x75, 0x56, 0xcc, 0xc6, 0x89, 0xb5, 0x4c, 0x2c, 0x9c, 0x53, 0x1b, 0xdd, 0x85, - 0xa9, 0x0c, 0x08, 0x5f, 0xb7, 0xc7, 0x18, 0xe5, 0xd7, 0x04, 0xe5, 0xa9, 0xb5, 0x1c, 0xbc, 0x83, - 0x36, 0x30, 0x9c, 0x4b, 0x1d, 0xdd, 0x80, 0x31, 0x76, 0x72, 0x96, 0x5b, 0xf5, 0xba, 0x68, 0x70, - 0x94, 0x35, 0xf8, 0x84, 0xe4, 0x23, 0x96, 0x4d, 0xf0, 0xc1, 0x5e, 0x09, 0xe2, 0x7f, 0x38, 0x59, - 0x1b, 0xdd, 0x66, 0x4a, 0xd8, 0x56, 0xe0, 0x46, 0xbb, 0x74, 0x57, 0x91, 0xbb, 0xd1, 0xd4, 0x58, - 0x5b, 0x81, 0x94, 0x8e, 0xaa, 0x34, 0xb5, 0x7a, 0x21, 0x4e, 0x12, 0xa4, 0x57, 0x41, 0x18, 0xd5, - 0x5c, 0x6f, 0x6a, 0x9c, 0xbf, 0xa7, 0xe4, 0x49, 0x5a, 0xa1, 0x85, 0x98, 0xc3, 0x98, 0x02, 0x96, - 0xfe, 0xb8, 0x41, 0x6f, 0xdc, 0x09, 0x86, 0x18, 0x2b, 0x60, 0x25, 0x00, 0xc7, 0x38, 0x94, 0x09, - 0x8e, 0xa2, 0xdd, 0x29, 0xc4, 0x50, 0xd5, 0x81, 0xb8, 0xb6, 0xf6, 0x09, 0x4c, 0xcb, 0xed, 0xdb, - 0x30, 0xaa, 0x8e, 0x09, 0x36, 0x26, 0xa8, 0x04, 0xbd, 0x8c, 0xed, 0x13, 0xe2, 0xd3, 0x41, 0xda, - 0x05, 0xc6, 0x12, 0x62, 0x5e, 0xce, 0xba, 0xe0, 0xde, 0x23, 0x73, 0xbb, 0x11, 0xe1, 0xb2, 0x88, - 0xa2, 0xd6, 0x05, 0x09, 0xc0, 0x31, 0x8e, 0xfd, 0x1f, 0x39, 0xfb, 0x1c, 0xdf, 0x12, 0x5d, 0xdc, - 0x8b, 0xcf, 0xc2, 0x00, 0x33, 0xfc, 0xf0, 0x03, 0xae, 0x9d, 0xed, 0x8d, 0x19, 0xe6, 0xab, 0xa2, - 0x1c, 0x2b, 0x0c, 0xf4, 0x2a, 0x8c, 0x54, 0xf5, 0x06, 0xc4, 0xa5, 0xae, 0x8e, 0x11, 0xa3, 0x75, - 0x6c, 0xe2, 0xa2, 0xcb, 0x30, 0xc0, 0x6c, 0x9c, 0xaa, 0x7e, 0x5d, 0x70, 0x9b, 0x92, 0x33, 0x19, - 0x28, 0x8b, 0xf2, 0x03, 0xed, 0x37, 0x56, 0xd8, 0xe8, 0x3c, 0xf4, 0xd1, 0x2e, 0x2c, 0x97, 0xc5, - 0x75, 0xaa, 0x24, 0x81, 0x57, 0x59, 0x29, 0x16, 0x50, 0xfb, 0x0f, 0x2c, 0xc6, 0x4b, 0xa5, 0xcf, - 0x7c, 0x74, 0x95, 0x5d, 0x1a, 0xec, 0x06, 0xd1, 0xb4, 0xf0, 0x8f, 0x6b, 0x37, 0x81, 0x82, 0x1d, - 0x24, 0xfe, 0x63, 0xa3, 0x26, 0x7a, 0x3b, 0x79, 0x33, 0x70, 0x86, 0xe2, 0x45, 0x39, 0x04, 0xc9, - 0xdb, 0xe1, 0x91, 0xf8, 0x8a, 0xa3, 0xfd, 0x69, 0x77, 0x45, 0xd8, 0x3f, 0x55, 0xd0, 0x56, 0x49, - 0x25, 0x72, 0x22, 0x82, 0xca, 0xd0, 0x7f, 0xc7, 0x71, 0x23, 0xd7, 0xdb, 0x14, 0x7c, 0x5f, 0xfb, - 0x8b, 0x8e, 0x55, 0xba, 0xc5, 0x2b, 0x70, 0xee, 0x45, 0xfc, 0xc1, 0x92, 0x0c, 0xa5, 0x18, 0xb4, - 0x3c, 0x8f, 0x52, 0x2c, 0x74, 0x4b, 0x11, 0xf3, 0x0a, 0x9c, 0xa2, 0xf8, 0x83, 0x25, 0x19, 0xf4, - 0x0e, 0x80, 0x3c, 0x21, 0x48, 0x4d, 0xc8, 0x0e, 0x9f, 0xed, 0x4c, 0x74, 0x4d, 0xd5, 0xe1, 0xc2, - 0xc9, 0xf8, 0x3f, 0xd6, 0xe8, 0xd9, 0x91, 0x36, 0xa7, 0x7a, 0x67, 0xd0, 0x27, 0xe9, 0x16, 0x75, - 0x82, 0x88, 0xd4, 0x66, 0x23, 0x31, 0x38, 0x4f, 0x77, 0xf7, 0x38, 0x5c, 0x73, 0x1b, 0x44, 0xdf, - 0xce, 0x82, 0x08, 0x8e, 0xe9, 0xd9, 0xbf, 0x53, 0x84, 0xa9, 0xbc, 0xee, 0xd2, 0x4d, 0x43, 0xee, - 0xba, 0xd1, 0x3c, 0x65, 0x6b, 0x2d, 0x73, 0xd3, 0x2c, 0x8a, 0x72, 0xac, 0x30, 0xe8, 0xea, 0x0d, - 0xdd, 0x4d, 0xf9, 0xb6, 0xef, 0x8d, 0x57, 0x6f, 0x85, 0x95, 0x62, 0x01, 0xa5, 0x78, 0x01, 0x71, - 0x42, 0x61, 0x7c, 0xa7, 0xad, 0x72, 0xcc, 0x4a, 0xb1, 0x80, 0xea, 0x52, 0xc6, 0x9e, 0x0e, 0x52, - 0x46, 0x63, 0x88, 0x7a, 0x1f, 0xec, 0x10, 0xa1, 0x4f, 0x03, 0x6c, 0xb8, 0x9e, 0x1b, 0x6e, 0x31, - 0xea, 0x7d, 0x87, 0xa6, 0xae, 0x98, 0xe2, 0x25, 0x45, 0x05, 0x6b, 0x14, 0xd1, 0x4b, 0x30, 0xa4, - 0x0e, 0x90, 0xe5, 0x05, 0xa6, 0xfa, 0xd7, 0x4c, 0xa9, 0xe2, 0xd3, 0x74, 0x01, 0xeb, 0x78, 0xf6, - 0x67, 0x93, 0xeb, 0x45, 0xec, 0x00, 0x6d, 0x7c, 0xad, 0x6e, 0xc7, 0xb7, 0xd0, 0x7e, 0x7c, 0xed, - 0x9f, 0x19, 0x84, 0x31, 0xa3, 0xb1, 0x56, 0xd8, 0xc5, 0x99, 0x7b, 0x85, 0x5e, 0x40, 0x4e, 0x44, - 0xc4, 0xfe, 0xb3, 0x3b, 0x6f, 0x15, 0xfd, 0x92, 0xa2, 0x3b, 0x80, 0xd7, 0x47, 0x9f, 0x86, 0xc1, - 0xba, 0x13, 0x32, 0x89, 0x25, 0x11, 0xfb, 0xae, 0x1b, 0x62, 0xf1, 0x83, 0xd0, 0x09, 0x23, 0xed, - 0xd6, 0xe7, 0xb4, 0x63, 0x92, 0xf4, 0xa6, 0xa4, 0xfc, 0x95, 0xb4, 0xee, 0x54, 0x9d, 0xa0, 0x4c, - 0xd8, 0x2e, 0xe6, 0x30, 0x74, 0x99, 0x1d, 0xad, 0x74, 0x55, 0xcc, 0x53, 0x6e, 0x94, 0x2d, 0xb3, - 0x5e, 0x83, 0xc9, 0x56, 0x30, 0x6c, 0x60, 0xc6, 0x6f, 0xb2, 0xbe, 0x36, 0x6f, 0xb2, 0xa7, 0xa0, - 0x9f, 0xfd, 0x50, 0x2b, 0x40, 0xcd, 0xc6, 0x32, 0x2f, 0xc6, 0x12, 0x9e, 0x5c, 0x30, 0x03, 0xdd, - 0x2d, 0x18, 0xfa, 0xea, 0x13, 0x8b, 0x9a, 0x99, 0x5d, 0x0c, 0xf0, 0x53, 0x4e, 0x2c, 0x79, 0x2c, - 0x61, 0xe8, 0x57, 0x2c, 0x40, 0x4e, 0x9d, 0xbe, 0x96, 0x69, 0xb1, 0x7a, 0xdc, 0x00, 0x63, 0xb5, - 0x5f, 0xed, 0x38, 0xec, 0xad, 0x70, 0x66, 0x36, 0x55, 0x9b, 0x4b, 0x4a, 0x5f, 0x11, 0x5d, 0x44, - 0x69, 0x04, 0xfd, 0x32, 0xba, 0xee, 0x86, 0xd1, 0xe7, 0xff, 0x26, 0x71, 0x39, 0x65, 0x74, 0x09, - 0xad, 0xeb, 0x8f, 0xaf, 0xa1, 0x43, 0x3e, 0xbe, 0x46, 0x72, 0x1f, 0x5e, 0xdf, 0x9f, 0x78, 0xc0, - 0x0c, 0xb3, 0x2f, 0x7f, 0xa2, 0xc3, 0x03, 0x46, 0x88, 0xd3, 0xbb, 0x79, 0xc6, 0x94, 0x85, 0x1e, - 0x78, 0x84, 0x75, 0xb9, 0xfd, 0x23, 0x78, 0x3d, 0x24, 0xc1, 0xdc, 0x29, 0xa9, 0x26, 0x3e, 0xd0, - 0x79, 0x0f, 0x4d, 0x6f, 0xfc, 0x43, 0x16, 0x4c, 0xa5, 0x07, 0x88, 0x77, 0x69, 0x6a, 0x94, 0xf5, - 0xdf, 0x6e, 0x37, 0x32, 0xa2, 0xf3, 0xd2, 0xdc, 0x75, 0x6a, 0x36, 0x87, 0x16, 0xce, 0x6d, 0x65, - 0xba, 0x05, 0x27, 0x73, 0xe6, 0x3d, 0x43, 0x6a, 0xbd, 0xa0, 0x4b, 0xad, 0x3b, 0xc8, 0x3a, 0x67, - 0xe4, 0xcc, 0xcc, 0xbc, 0xd5, 0x72, 0xbc, 0xc8, 0x8d, 0x76, 0x75, 0x29, 0xb7, 0x07, 0xe6, 0x80, - 0xa0, 0x4f, 0x41, 0x6f, 0xdd, 0xf5, 0x5a, 0x77, 0xc5, 0x4d, 0x79, 0x3e, 0xfb, 0x11, 0xe3, 0xb5, - 0xee, 0x9a, 0x43, 0x5c, 0xa2, 0x1b, 0x92, 0x95, 0x1f, 0xec, 0x95, 0x50, 0x1a, 0x01, 0x73, 0xaa, - 0xf6, 0xd3, 0x30, 0xba, 0xe0, 0x90, 0x86, 0xef, 0x2d, 0x7a, 0xb5, 0xa6, 0xef, 0x7a, 0x11, 0x9a, - 0x82, 0x1e, 0xc6, 0x22, 0xf2, 0x0b, 0xb2, 0x87, 0x0e, 0x21, 0x66, 0x25, 0xf6, 0x26, 0x1c, 0x5f, - 0xf0, 0xef, 0x78, 0x77, 0x9c, 0xa0, 0x36, 0x5b, 0x5e, 0xd6, 0xa4, 0x7e, 0xab, 0x52, 0xea, 0x64, - 0xe5, 0xbf, 0xe9, 0xb5, 0x9a, 0x7c, 0x29, 0x2d, 0xb9, 0x75, 0x92, 0x23, 0x9b, 0xfd, 0x99, 0x82, - 0xd1, 0x52, 0x8c, 0xaf, 0x34, 0x8b, 0x56, 0xae, 0x51, 0xc2, 0x5b, 0x30, 0xb0, 0xe1, 0x92, 0x7a, - 0x0d, 0x93, 0x0d, 0x31, 0x1b, 0x4f, 0xe6, 0x9b, 0x2d, 0x2e, 0x51, 0x4c, 0xa5, 0x02, 0x65, 0x32, - 0xab, 0x25, 0x51, 0x19, 0x2b, 0x32, 0x68, 0x1b, 0xc6, 0xe5, 0x9c, 0x49, 0xa8, 0x38, 0xb5, 0x9f, - 0x6a, 0xb7, 0x08, 0x4d, 0xe2, 0xcc, 0x84, 0x1b, 0x27, 0xc8, 0xe0, 0x14, 0x61, 0x74, 0x1a, 0x7a, - 0x1a, 0x94, 0x3f, 0xe9, 0x61, 0xc3, 0xcf, 0x84, 0x54, 0x4c, 0xde, 0xc6, 0x4a, 0xed, 0x9f, 0xb3, - 0xe0, 0x64, 0x6a, 0x64, 0x84, 0xdc, 0xf1, 0x01, 0xcf, 0x42, 0x52, 0x0e, 0x58, 0xe8, 0x2c, 0x07, - 0xb4, 0xff, 0x3b, 0x0b, 0x8e, 0x2d, 0x36, 0x9a, 0xd1, 0xee, 0x82, 0x6b, 0x5a, 0x10, 0xbc, 0x0c, - 0x7d, 0x0d, 0x52, 0x73, 0x5b, 0x0d, 0x31, 0x73, 0x25, 0x79, 0x87, 0xaf, 0xb0, 0x52, 0x7a, 0x0e, - 0x54, 0x22, 0x3f, 0x70, 0x36, 0x09, 0x2f, 0xc0, 0x02, 0x9d, 0x71, 0x42, 0xee, 0x3d, 0x72, 0xdd, - 0x6d, 0xb8, 0xd1, 0xfd, 0xed, 0x2e, 0xa1, 0xfc, 0x97, 0x44, 0x70, 0x4c, 0xcf, 0xfe, 0x96, 0x05, - 0x63, 0x72, 0xdd, 0xcf, 0xd6, 0x6a, 0x01, 0x09, 0x43, 0x34, 0x0d, 0x05, 0xb7, 0x29, 0x7a, 0x09, - 0xa2, 0x97, 0x85, 0xe5, 0x32, 0x2e, 0xb8, 0x4d, 0xf9, 0xe8, 0x62, 0x6c, 0x42, 0xd1, 0xb4, 0x83, - 0xb8, 0x2a, 0xca, 0xb1, 0xc2, 0x40, 0x17, 0x60, 0xc0, 0xf3, 0x6b, 0xfc, 0xdd, 0x22, 0x34, 0xe1, - 0x14, 0x73, 0x55, 0x94, 0x61, 0x05, 0x45, 0x65, 0x18, 0xe4, 0x56, 0xb2, 0xf1, 0xa2, 0xed, 0xca, - 0xd6, 0x96, 0x7d, 0xd9, 0x9a, 0xac, 0x89, 0x63, 0x22, 0xf6, 0x1f, 0x59, 0x30, 0x2c, 0xbf, 0xac, - 0xcb, 0x17, 0x25, 0xdd, 0x5a, 0xf1, 0x6b, 0x32, 0xde, 0x5a, 0xf4, 0x45, 0xc8, 0x20, 0xc6, 0x43, - 0xb0, 0x78, 0xa8, 0x87, 0xe0, 0x25, 0x18, 0x72, 0x9a, 0xcd, 0xb2, 0xf9, 0x8a, 0x64, 0x4b, 0x69, - 0x36, 0x2e, 0xc6, 0x3a, 0x8e, 0xfd, 0xb3, 0x05, 0x18, 0x95, 0x5f, 0x50, 0x69, 0xdd, 0x0e, 0x49, - 0x84, 0xd6, 0x60, 0xd0, 0xe1, 0xb3, 0x44, 0xe4, 0x22, 0x7f, 0x2c, 0x5b, 0xba, 0x69, 0x4c, 0x69, - 0xcc, 0x0e, 0xcf, 0xca, 0xda, 0x38, 0x26, 0x84, 0xea, 0x30, 0xe1, 0xf9, 0x11, 0x63, 0x8d, 0x14, - 0xbc, 0x9d, 0xc2, 0x39, 0x49, 0xfd, 0x94, 0xa0, 0x3e, 0xb1, 0x9a, 0xa4, 0x82, 0xd3, 0x84, 0xd1, - 0xa2, 0x94, 0x18, 0x17, 0xf3, 0x45, 0x7d, 0xfa, 0xc4, 0x65, 0x0b, 0x8c, 0xed, 0xdf, 0xb7, 0x60, - 0x50, 0xa2, 0x1d, 0x85, 0x6d, 0xc1, 0x0a, 0xf4, 0x87, 0x6c, 0x12, 0xe4, 0xd0, 0xd8, 0xed, 0x3a, - 0xce, 0xe7, 0x2b, 0xe6, 0xf8, 0xf8, 0xff, 0x10, 0x4b, 0x1a, 0x4c, 0x61, 0xa8, 0xba, 0xff, 0x3e, - 0x51, 0x18, 0xaa, 0xfe, 0xe4, 0x5c, 0x4a, 0x7f, 0xc7, 0xfa, 0xac, 0x49, 0xe0, 0xe9, 0xc3, 0xa4, - 0x19, 0x90, 0x0d, 0xf7, 0x6e, 0xf2, 0x61, 0x52, 0x66, 0xa5, 0x58, 0x40, 0xd1, 0x3b, 0x30, 0x5c, - 0x95, 0x9a, 0xa2, 0x78, 0x87, 0x9f, 0x6f, 0xab, 0xb5, 0x54, 0x0a, 0x6e, 0x2e, 0xe9, 0x9c, 0xd7, - 0xea, 0x63, 0x83, 0x9a, 0x69, 0x05, 0x56, 0xec, 0x64, 0x05, 0x16, 0xd3, 0xcd, 0xb7, 0x89, 0xfa, - 0x79, 0x0b, 0xfa, 0xb8, 0x86, 0xa0, 0x3b, 0x05, 0x8d, 0xa6, 0xef, 0x8f, 0xc7, 0xee, 0x26, 0x2d, - 0x14, 0x9c, 0x0d, 0x5a, 0x81, 0x41, 0xf6, 0x83, 0x69, 0x38, 0x8a, 0xf9, 0x3e, 0x63, 0xbc, 0x55, - 0xbd, 0x83, 0x37, 0x65, 0x35, 0x1c, 0x53, 0xb0, 0x7f, 0xba, 0x48, 0x4f, 0xb7, 0x18, 0xd5, 0xb8, - 0xf4, 0xad, 0x87, 0x77, 0xe9, 0x17, 0x1e, 0xd6, 0xa5, 0xbf, 0x09, 0x63, 0x55, 0xcd, 0x3a, 0x20, - 0x9e, 0xc9, 0x0b, 0x6d, 0x17, 0x89, 0x66, 0x48, 0xc0, 0x65, 0xa8, 0xf3, 0x26, 0x11, 0x9c, 0xa4, - 0x8a, 0x3e, 0x09, 0xc3, 0x7c, 0x9e, 0x45, 0x2b, 0xdc, 0x90, 0xee, 0x89, 0xfc, 0xf5, 0xa2, 0x37, - 0xc1, 0x65, 0xee, 0x5a, 0x75, 0x6c, 0x10, 0xb3, 0xff, 0xc9, 0x02, 0xb4, 0xd8, 0xdc, 0x22, 0x0d, - 0x12, 0x38, 0xf5, 0x58, 0xc9, 0xf7, 0x25, 0x0b, 0xa6, 0x48, 0xaa, 0x78, 0xde, 0x6f, 0x34, 0xc4, - 0x93, 0x3e, 0x47, 0xea, 0xb4, 0x98, 0x53, 0x27, 0x66, 0xeb, 0xf3, 0x30, 0x70, 0x6e, 0x7b, 0x68, - 0x05, 0x26, 0xf9, 0x2d, 0xa9, 0x00, 0x9a, 0xad, 0xdd, 0x23, 0x82, 0xf0, 0xe4, 0x5a, 0x1a, 0x05, - 0x67, 0xd5, 0xb3, 0x7f, 0x7f, 0x04, 0x72, 0x7b, 0xf1, 0x81, 0x76, 0xf3, 0x03, 0xed, 0xe6, 0x07, - 0xda, 0xcd, 0x0f, 0xb4, 0x9b, 0x1f, 0x68, 0x37, 0x3f, 0xd0, 0x6e, 0xbe, 0x4f, 0xb5, 0x9b, 0xff, - 0xa5, 0x05, 0xc7, 0xd5, 0xf5, 0x65, 0x3c, 0xd8, 0x3f, 0x07, 0x93, 0x7c, 0xbb, 0xcd, 0xd7, 0x1d, - 0xb7, 0xb1, 0x46, 0x1a, 0xcd, 0xba, 0x13, 0x49, 0x1b, 0xa6, 0x4b, 0x99, 0x2b, 0x37, 0xe1, 0x28, - 0x61, 0x54, 0xe4, 0x1e, 0x67, 0x19, 0x00, 0x9c, 0xd5, 0x8c, 0xfd, 0x3b, 0x03, 0xd0, 0xbb, 0xb8, - 0x43, 0xbc, 0xe8, 0x08, 0x9e, 0x36, 0x55, 0x18, 0x75, 0xbd, 0x1d, 0xbf, 0xbe, 0x43, 0x6a, 0x1c, - 0x7e, 0x98, 0x17, 0xf8, 0x09, 0x41, 0x7a, 0x74, 0xd9, 0x20, 0x81, 0x13, 0x24, 0x1f, 0x86, 0x8e, - 0xe8, 0x0a, 0xf4, 0xf1, 0xcb, 0x47, 0x28, 0x88, 0x32, 0xcf, 0x6c, 0x36, 0x88, 0xe2, 0x4a, 0x8d, - 0xf5, 0x57, 0xfc, 0x72, 0x13, 0xd5, 0xd1, 0x67, 0x61, 0x74, 0xc3, 0x0d, 0xc2, 0x68, 0xcd, 0x6d, - 0xd0, 0xab, 0xa1, 0xd1, 0xbc, 0x0f, 0x9d, 0x90, 0x1a, 0x87, 0x25, 0x83, 0x12, 0x4e, 0x50, 0x46, - 0x9b, 0x30, 0x52, 0x77, 0xf4, 0xa6, 0xfa, 0x0f, 0xdd, 0x94, 0xba, 0x1d, 0xae, 0xeb, 0x84, 0xb0, - 0x49, 0x97, 0x6e, 0xa7, 0x2a, 0x53, 0x6b, 0x0c, 0x30, 0x71, 0x86, 0xda, 0x4e, 0x5c, 0x9f, 0xc1, - 0x61, 0x94, 0x41, 0x63, 0xee, 0x06, 0x83, 0x26, 0x83, 0xa6, 0x39, 0x15, 0x7c, 0x06, 0x06, 0x09, - 0x1d, 0x42, 0x4a, 0x58, 0x5c, 0x30, 0x17, 0xbb, 0xeb, 0xeb, 0x8a, 0x5b, 0x0d, 0x7c, 0x53, 0x1b, - 0xb7, 0x28, 0x29, 0xe1, 0x98, 0x28, 0x9a, 0x87, 0xbe, 0x90, 0x04, 0xae, 0x92, 0xf8, 0xb7, 0x99, - 0x46, 0x86, 0xc6, 0x5d, 0x1a, 0xf9, 0x6f, 0x2c, 0xaa, 0xd2, 0xe5, 0xe5, 0x30, 0x51, 0x2c, 0xbb, - 0x0c, 0xb4, 0xe5, 0x35, 0xcb, 0x4a, 0xb1, 0x80, 0xa2, 0x37, 0xa1, 0x3f, 0x20, 0x75, 0xa6, 0xee, - 0x1d, 0xe9, 0x7e, 0x91, 0x73, 0xed, 0x31, 0xaf, 0x87, 0x25, 0x01, 0x74, 0x0d, 0x50, 0x40, 0x28, - 0x83, 0xe7, 0x7a, 0x9b, 0xca, 0x08, 0x5f, 0x1c, 0xb4, 0x8a, 0x91, 0xc6, 0x31, 0x86, 0xf4, 0x66, - 0xc5, 0x19, 0xd5, 0xd0, 0x15, 0x98, 0x50, 0xa5, 0xcb, 0x5e, 0x18, 0x39, 0xf4, 0x80, 0x1b, 0x63, - 0xb4, 0x94, 0x7c, 0x05, 0x27, 0x11, 0x70, 0xba, 0x8e, 0xfd, 0x6b, 0x16, 0xf0, 0x71, 0x3e, 0x02, - 0xa9, 0xc2, 0xeb, 0xa6, 0x54, 0xe1, 0x54, 0xee, 0xcc, 0xe5, 0x48, 0x14, 0x7e, 0xcd, 0x82, 0x21, - 0x6d, 0x66, 0xe3, 0x35, 0x6b, 0xb5, 0x59, 0xb3, 0x2d, 0x18, 0xa7, 0x2b, 0xfd, 0xc6, 0xed, 0x90, - 0x04, 0x3b, 0xa4, 0xc6, 0x16, 0x66, 0xe1, 0xfe, 0x16, 0xa6, 0x32, 0xf8, 0xbd, 0x9e, 0x20, 0x88, - 0x53, 0x4d, 0xd8, 0x9f, 0x91, 0x5d, 0x55, 0xf6, 0xd1, 0x55, 0x35, 0xe7, 0x09, 0xfb, 0x68, 0x35, - 0xab, 0x38, 0xc6, 0xa1, 0x5b, 0x6d, 0xcb, 0x0f, 0xa3, 0xa4, 0x7d, 0xf4, 0x55, 0x3f, 0x8c, 0x30, - 0x83, 0xd8, 0x2f, 0x00, 0x2c, 0xde, 0x25, 0x55, 0xbe, 0x62, 0xf5, 0x47, 0x8f, 0x95, 0xff, 0xe8, - 0xb1, 0xff, 0xd2, 0x82, 0xd1, 0xa5, 0x79, 0xe3, 0xe6, 0x9a, 0x01, 0xe0, 0x2f, 0xb5, 0x5b, 0xb7, - 0x56, 0xa5, 0x91, 0x0e, 0xb7, 0x53, 0x50, 0xa5, 0x58, 0xc3, 0x40, 0xa7, 0xa0, 0x58, 0x6f, 0x79, - 0x42, 0xec, 0xd9, 0x4f, 0xaf, 0xc7, 0xeb, 0x2d, 0x0f, 0xd3, 0x32, 0xcd, 0x93, 0xad, 0xd8, 0xb5, - 0x27, 0x5b, 0xc7, 0x80, 0x3a, 0xa8, 0x04, 0xbd, 0x77, 0xee, 0xb8, 0x35, 0x1e, 0x27, 0x40, 0x18, - 0x10, 0xdd, 0xba, 0xb5, 0xbc, 0x10, 0x62, 0x5e, 0x6e, 0x7f, 0xb9, 0x08, 0xd3, 0x4b, 0x75, 0x72, - 0xf7, 0x3d, 0xc6, 0x4a, 0xe8, 0xd6, 0x0f, 0xef, 0x70, 0x02, 0xa4, 0xc3, 0xfa, 0x5a, 0x76, 0x1e, - 0x8f, 0x0d, 0xe8, 0xe7, 0xe6, 0xc1, 0x32, 0x72, 0x42, 0xa6, 0x52, 0x36, 0x7f, 0x40, 0x66, 0xb8, - 0x99, 0xb1, 0x50, 0xca, 0xaa, 0x0b, 0x53, 0x94, 0x62, 0x49, 0x7c, 0xfa, 0x15, 0x18, 0xd6, 0x31, - 0x0f, 0xe5, 0xf5, 0xfc, 0xc3, 0x45, 0x18, 0xa7, 0x3d, 0x78, 0xa8, 0x13, 0xb1, 0x9e, 0x9e, 0x88, - 0x07, 0xed, 0xf9, 0xda, 0x79, 0x36, 0xde, 0x49, 0xce, 0xc6, 0xa5, 0xbc, 0xd9, 0x38, 0xea, 0x39, - 0xf8, 0x11, 0x0b, 0x26, 0x97, 0xea, 0x7e, 0x75, 0x3b, 0xe1, 0x9d, 0xfa, 0x12, 0x0c, 0xd1, 0xe3, - 0x38, 0x34, 0x02, 0xb5, 0x18, 0xa1, 0x7b, 0x04, 0x08, 0xeb, 0x78, 0x5a, 0xb5, 0xf5, 0xf5, 0xe5, - 0x85, 0xac, 0x88, 0x3f, 0x02, 0x84, 0x75, 0x3c, 0xfb, 0xcf, 0x2d, 0x38, 0x73, 0x65, 0x7e, 0x31, - 0x5e, 0x8a, 0xa9, 0xa0, 0x43, 0xe7, 0xa1, 0xaf, 0x59, 0xd3, 0xba, 0x12, 0x8b, 0x85, 0x17, 0x58, - 0x2f, 0x04, 0xf4, 0xfd, 0x12, 0xdf, 0x6b, 0x1d, 0xe0, 0x0a, 0x2e, 0xcf, 0x8b, 0x73, 0x57, 0x6a, - 0x81, 0xac, 0x5c, 0x2d, 0xd0, 0x13, 0xd0, 0x4f, 0xef, 0x05, 0xb7, 0x2a, 0xfb, 0xcd, 0xcd, 0x2e, - 0x78, 0x11, 0x96, 0x30, 0xfb, 0x57, 0x2d, 0x98, 0xbc, 0xe2, 0x46, 0xf4, 0xd2, 0x4e, 0x46, 0xd5, - 0xa1, 0xb7, 0x76, 0xe8, 0x46, 0x7e, 0xb0, 0x9b, 0x8c, 0xaa, 0x83, 0x15, 0x04, 0x6b, 0x58, 0xfc, - 0x83, 0x76, 0x5c, 0xe6, 0xef, 0x52, 0x30, 0xf5, 0x6e, 0x58, 0x94, 0x63, 0x85, 0x41, 0xc7, 0xab, - 0xe6, 0x06, 0x4c, 0x64, 0xb9, 0x2b, 0x0e, 0x6e, 0x35, 0x5e, 0x0b, 0x12, 0x80, 0x63, 0x1c, 0xfb, - 0x1f, 0x2c, 0x28, 0x5d, 0xe1, 0x5e, 0xbb, 0x1b, 0x61, 0xce, 0xa1, 0xfb, 0x02, 0x0c, 0x12, 0xa9, - 0x20, 0x10, 0xbd, 0x56, 0x8c, 0xa8, 0xd2, 0x1c, 0xf0, 0xe0, 0x3e, 0x0a, 0xaf, 0x0b, 0x17, 0xfa, - 0xc3, 0xf9, 0x40, 0x2f, 0x01, 0x22, 0x7a, 0x5b, 0x7a, 0xb4, 0x23, 0x16, 0x36, 0x65, 0x31, 0x05, - 0xc5, 0x19, 0x35, 0xec, 0x9f, 0xb3, 0xe0, 0xb8, 0xfa, 0xe0, 0xf7, 0xdd, 0x67, 0xda, 0x5f, 0x2f, - 0xc0, 0xc8, 0xd5, 0xb5, 0xb5, 0xf2, 0x15, 0x12, 0x69, 0xab, 0xb2, 0xbd, 0xda, 0x1f, 0x6b, 0xda, - 0xcb, 0x76, 0x6f, 0xc4, 0x56, 0xe4, 0xd6, 0x67, 0x78, 0x0c, 0xbf, 0x99, 0x65, 0x2f, 0xba, 0x11, - 0x54, 0xa2, 0xc0, 0xf5, 0x36, 0x33, 0x57, 0xba, 0xe4, 0x59, 0x8a, 0x79, 0x3c, 0x0b, 0x7a, 0x01, - 0xfa, 0x58, 0x10, 0x41, 0x39, 0x09, 0x8f, 0xa8, 0x27, 0x16, 0x2b, 0x3d, 0xd8, 0x2b, 0x0d, 0xae, - 0xe3, 0x65, 0xfe, 0x07, 0x0b, 0x54, 0xb4, 0x0e, 0x43, 0x5b, 0x51, 0xd4, 0xbc, 0x4a, 0x9c, 0x1a, - 0x09, 0xe4, 0x29, 0x7b, 0x36, 0xeb, 0x94, 0xa5, 0x83, 0xc0, 0xd1, 0xe2, 0x83, 0x29, 0x2e, 0x0b, - 0xb1, 0x4e, 0xc7, 0xae, 0x00, 0xc4, 0xb0, 0x07, 0xa4, 0xb8, 0xb1, 0xd7, 0x60, 0x90, 0x7e, 0xee, - 0x6c, 0xdd, 0x75, 0xda, 0xab, 0xc6, 0x9f, 0x81, 0x41, 0xa9, 0xf8, 0x0e, 0x45, 0x88, 0x0f, 0x76, - 0x23, 0x49, 0xbd, 0x78, 0x88, 0x63, 0xb8, 0xfd, 0x38, 0x08, 0x0b, 0xe0, 0x76, 0x24, 0xed, 0x0d, - 0x38, 0xc6, 0x4c, 0x99, 0x9d, 0x68, 0xcb, 0x58, 0xa3, 0x9d, 0x17, 0xc3, 0xb3, 0xe2, 0x5d, 0xc7, - 0xbf, 0x6c, 0x4a, 0x73, 0x21, 0x1f, 0x96, 0x14, 0xe3, 0x37, 0x9e, 0xfd, 0xf7, 0x3d, 0xf0, 0xc8, - 0x72, 0x25, 0x3f, 0x36, 0xd5, 0x65, 0x18, 0xe6, 0xec, 0x22, 0x5d, 0x1a, 0x4e, 0x5d, 0xb4, 0xab, - 0x24, 0xa0, 0x6b, 0x1a, 0x0c, 0x1b, 0x98, 0xe8, 0x0c, 0x14, 0xdd, 0x77, 0xbd, 0xa4, 0x83, 0xe5, - 0xf2, 0x5b, 0xab, 0x98, 0x96, 0x53, 0x30, 0xe5, 0x3c, 0xf9, 0x91, 0xae, 0xc0, 0x8a, 0xfb, 0x7c, - 0x1d, 0x46, 0xdd, 0xb0, 0x1a, 0xba, 0xcb, 0x1e, 0xdd, 0xa7, 0xda, 0x4e, 0x57, 0x32, 0x07, 0xda, - 0x69, 0x05, 0xc5, 0x09, 0x6c, 0xed, 0x7e, 0xe9, 0xed, 0x9a, 0x7b, 0xed, 0x18, 0x19, 0x83, 0x1e, - 0xff, 0x4d, 0xf6, 0x75, 0x21, 0x13, 0xc1, 0x8b, 0xe3, 0x9f, 0x7f, 0x70, 0x88, 0x25, 0x8c, 0x3e, - 0xe8, 0xaa, 0x5b, 0x4e, 0x73, 0xb6, 0x15, 0x6d, 0x2d, 0xb8, 0x61, 0xd5, 0xdf, 0x21, 0xc1, 0x2e, - 0x7b, 0x8b, 0x0f, 0xc4, 0x0f, 0x3a, 0x05, 0x98, 0xbf, 0x3a, 0x5b, 0xa6, 0x98, 0x38, 0x5d, 0x07, - 0xcd, 0xc2, 0x98, 0x2c, 0xac, 0x90, 0x90, 0x5d, 0x01, 0x43, 0x8c, 0x8c, 0x72, 0x79, 0x14, 0xc5, - 0x8a, 0x48, 0x12, 0xdf, 0x64, 0x70, 0xe1, 0x41, 0x30, 0xb8, 0x2f, 0xc3, 0x88, 0xeb, 0xb9, 0x91, - 0xeb, 0x44, 0x3e, 0xd7, 0x1f, 0xf1, 0x67, 0x37, 0x13, 0x30, 0x2f, 0xeb, 0x00, 0x6c, 0xe2, 0xd9, - 0xff, 0x5f, 0x0f, 0x4c, 0xb0, 0x69, 0xfb, 0x60, 0x85, 0x7d, 0x2f, 0xad, 0xb0, 0xf5, 0xf4, 0x0a, - 0x7b, 0x10, 0x9c, 0xfb, 0x7d, 0x2f, 0xb3, 0x2f, 0x58, 0x30, 0xc1, 0x64, 0xdc, 0xc6, 0x32, 0xbb, - 0x08, 0x83, 0x81, 0xe1, 0x8d, 0x3a, 0xa8, 0x2b, 0xb5, 0xa4, 0x63, 0x69, 0x8c, 0x83, 0xde, 0x00, - 0x68, 0xc6, 0x32, 0xf4, 0x82, 0x11, 0x42, 0x14, 0x72, 0xc5, 0xe7, 0x5a, 0x1d, 0xfb, 0xb3, 0x30, - 0xa8, 0xdc, 0x4d, 0xa5, 0xbf, 0xb9, 0x95, 0xe3, 0x6f, 0xde, 0x99, 0x8d, 0x90, 0xb6, 0x71, 0xc5, - 0x4c, 0xdb, 0xb8, 0xaf, 0x5a, 0x10, 0x6b, 0x38, 0xd0, 0x5b, 0x30, 0xd8, 0xf4, 0x99, 0x41, 0x74, - 0x20, 0xbd, 0x0c, 0x1e, 0x6f, 0xab, 0x22, 0xe1, 0x71, 0x02, 0x03, 0x3e, 0x1d, 0x65, 0x59, 0x15, - 0xc7, 0x54, 0xd0, 0x35, 0xe8, 0x6f, 0x06, 0xa4, 0x12, 0xb1, 0x20, 0x56, 0xdd, 0x13, 0xe4, 0xcb, - 0x97, 0x57, 0xc4, 0x92, 0x82, 0xfd, 0x1b, 0x05, 0x18, 0x4f, 0xa2, 0xa2, 0xd7, 0xa0, 0x87, 0xdc, - 0x25, 0x55, 0xd1, 0xdf, 0x4c, 0x9e, 0x20, 0x96, 0x91, 0xf0, 0x01, 0xa0, 0xff, 0x31, 0xab, 0x85, - 0xae, 0x42, 0x3f, 0x65, 0x08, 0xae, 0xa8, 0x80, 0x8d, 0x8f, 0xe6, 0x31, 0x15, 0x8a, 0xb3, 0xe2, - 0x9d, 0x13, 0x45, 0x58, 0x56, 0x67, 0x06, 0x69, 0xd5, 0x66, 0x85, 0xbe, 0xb5, 0xa2, 0x76, 0x22, - 0x81, 0xb5, 0xf9, 0x32, 0x47, 0x12, 0xd4, 0xb8, 0x41, 0x9a, 0x2c, 0xc4, 0x31, 0x11, 0xf4, 0x06, - 0xf4, 0x86, 0x75, 0x42, 0x9a, 0xc2, 0xe2, 0x20, 0x53, 0xca, 0x59, 0xa1, 0x08, 0x82, 0x12, 0x93, - 0x8a, 0xb0, 0x02, 0xcc, 0x2b, 0xda, 0xbf, 0x65, 0x01, 0x70, 0x0b, 0x3e, 0xc7, 0xdb, 0x24, 0x47, - 0xa0, 0x18, 0x58, 0x80, 0x9e, 0xb0, 0x49, 0xaa, 0xed, 0xac, 0xfd, 0xe3, 0xfe, 0x54, 0x9a, 0xa4, - 0x1a, 0xaf, 0x59, 0xfa, 0x0f, 0xb3, 0xda, 0xf6, 0x8f, 0x02, 0x8c, 0xc6, 0x68, 0xcb, 0x11, 0x69, - 0xa0, 0xe7, 0x8c, 0x28, 0x37, 0xa7, 0x12, 0x51, 0x6e, 0x06, 0x19, 0xb6, 0x26, 0x83, 0xfe, 0x2c, - 0x14, 0x1b, 0xce, 0x5d, 0x21, 0x64, 0x7c, 0xa6, 0x7d, 0x37, 0x28, 0xfd, 0x99, 0x15, 0xe7, 0x2e, - 0x7f, 0x87, 0x3f, 0x23, 0xf7, 0xd8, 0x8a, 0x73, 0xb7, 0xa3, 0x45, 0x3a, 0x6d, 0x84, 0xb5, 0xe5, - 0x7a, 0xc2, 0x38, 0xad, 0xab, 0xb6, 0x5c, 0x2f, 0xd9, 0x96, 0xeb, 0x75, 0xd1, 0x96, 0xeb, 0xa1, - 0x7b, 0xd0, 0x2f, 0x6c, 0x47, 0x45, 0xf8, 0xbd, 0x8b, 0x5d, 0xb4, 0x27, 0x4c, 0x4f, 0x79, 0x9b, - 0x17, 0xa5, 0x9c, 0x41, 0x94, 0x76, 0x6c, 0x57, 0x36, 0x88, 0xfe, 0x2b, 0x0b, 0x46, 0xc5, 0x6f, - 0x4c, 0xde, 0x6d, 0x91, 0x30, 0x12, 0x7c, 0xf8, 0x47, 0xba, 0xef, 0x83, 0xa8, 0xc8, 0xbb, 0xf2, - 0x11, 0x79, 0x65, 0x9a, 0xc0, 0x8e, 0x3d, 0x4a, 0xf4, 0x02, 0xfd, 0x86, 0x05, 0xc7, 0x1a, 0xce, - 0x5d, 0xde, 0x22, 0x2f, 0xc3, 0x4e, 0xe4, 0xfa, 0xc2, 0x06, 0xe3, 0xb5, 0xee, 0xa6, 0x3f, 0x55, - 0x9d, 0x77, 0x52, 0x2a, 0x5c, 0x8f, 0x65, 0xa1, 0x74, 0xec, 0x6a, 0x66, 0xbf, 0xa6, 0x37, 0x60, - 0x40, 0xae, 0xb7, 0x87, 0x69, 0x18, 0xcf, 0xda, 0x11, 0x6b, 0xed, 0xa1, 0xb6, 0xf3, 0x59, 0x18, - 0xd6, 0xd7, 0xd8, 0x43, 0x6d, 0xeb, 0x5d, 0x98, 0xcc, 0x58, 0x4b, 0x0f, 0xb5, 0xc9, 0x3b, 0x70, - 0x2a, 0x77, 0x7d, 0x3c, 0x54, 0xc7, 0x86, 0xaf, 0x5b, 0xfa, 0x39, 0x78, 0x04, 0xda, 0x99, 0x79, - 0x53, 0x3b, 0x73, 0xb6, 0xfd, 0xce, 0xc9, 0x51, 0xd1, 0xbc, 0xa3, 0x77, 0x9a, 0x9e, 0xea, 0xe8, - 0x4d, 0xe8, 0xab, 0xd3, 0x12, 0x69, 0x81, 0x6c, 0x77, 0xde, 0x91, 0x31, 0x5f, 0xcc, 0xca, 0x43, - 0x2c, 0x28, 0xd8, 0x5f, 0xb1, 0x20, 0xc3, 0x35, 0x83, 0xf2, 0x49, 0x2d, 0xb7, 0xc6, 0x86, 0xa4, - 0x18, 0xf3, 0x49, 0x2a, 0x08, 0xcc, 0x19, 0x28, 0x6e, 0xba, 0x35, 0xe1, 0x59, 0xac, 0xc0, 0x57, - 0x28, 0x78, 0xd3, 0xad, 0xa1, 0x25, 0x40, 0x61, 0xab, 0xd9, 0xac, 0x33, 0xb3, 0x25, 0xa7, 0x7e, - 0x25, 0xf0, 0x5b, 0x4d, 0x6e, 0x6e, 0x5c, 0xe4, 0x42, 0xa2, 0x4a, 0x0a, 0x8a, 0x33, 0x6a, 0xd8, - 0xbf, 0x6b, 0x41, 0xcf, 0x11, 0x4c, 0x13, 0x36, 0xa7, 0xe9, 0xb9, 0x5c, 0xd2, 0x22, 0x6b, 0xc3, - 0x0c, 0x76, 0xee, 0x2c, 0xde, 0x8d, 0x88, 0x17, 0x32, 0x86, 0x23, 0x73, 0xd6, 0xf6, 0x2c, 0x98, - 0xbc, 0xee, 0x3b, 0xb5, 0x39, 0xa7, 0xee, 0x78, 0x55, 0x12, 0x2c, 0x7b, 0x9b, 0x87, 0xb2, 0xed, - 0x2f, 0x74, 0xb4, 0xed, 0xbf, 0x0c, 0x7d, 0x6e, 0x53, 0x0b, 0xfb, 0x7e, 0x8e, 0xce, 0xee, 0x72, - 0x59, 0x44, 0x7c, 0x47, 0x46, 0xe3, 0xac, 0x14, 0x0b, 0x7c, 0xba, 0x2c, 0xb9, 0x51, 0x5d, 0x4f, - 0xfe, 0xb2, 0xa4, 0x6f, 0x9d, 0x64, 0x38, 0x33, 0xc3, 0xfc, 0x7b, 0x0b, 0x8c, 0x26, 0x84, 0x07, - 0x23, 0x86, 0x7e, 0x97, 0x7f, 0xa9, 0x58, 0x9b, 0x4f, 0x66, 0xbf, 0x41, 0x52, 0x03, 0xa3, 0xf9, - 0xe6, 0xf1, 0x02, 0x2c, 0x09, 0xd9, 0x97, 0x21, 0x33, 0xfc, 0x4c, 0x67, 0xf9, 0x92, 0xfd, 0x09, - 0x98, 0x60, 0x35, 0x0f, 0x29, 0xbb, 0xb1, 0x13, 0x52, 0xf1, 0x8c, 0x08, 0xbe, 0xf6, 0xff, 0x6d, - 0x01, 0x5a, 0xf1, 0x6b, 0xee, 0xc6, 0xae, 0x20, 0xce, 0xbf, 0xff, 0x5d, 0x28, 0xf1, 0xc7, 0x71, - 0x32, 0xca, 0xed, 0x7c, 0xdd, 0x09, 0x43, 0x4d, 0x22, 0xff, 0xa4, 0x68, 0xb7, 0xb4, 0xd6, 0x1e, - 0x1d, 0x77, 0xa2, 0x87, 0xde, 0x4a, 0x04, 0x1d, 0xfc, 0x68, 0x2a, 0xe8, 0xe0, 0x93, 0x99, 0x76, - 0x31, 0xe9, 0xde, 0xcb, 0x60, 0x84, 0xf6, 0x17, 0x2d, 0x18, 0x5b, 0x4d, 0x44, 0x6d, 0x3d, 0xcf, - 0x8c, 0x04, 0x32, 0x34, 0x4d, 0x15, 0x56, 0x8a, 0x05, 0xf4, 0x81, 0x4b, 0x62, 0xff, 0xd5, 0x82, - 0x38, 0xdc, 0xd5, 0x11, 0xb0, 0xdc, 0xf3, 0x06, 0xcb, 0x9d, 0xf9, 0x7c, 0x51, 0xdd, 0xc9, 0xe3, - 0xb8, 0xd1, 0x35, 0x35, 0x27, 0x6d, 0x5e, 0x2e, 0x31, 0x19, 0xbe, 0xcf, 0x46, 0xcd, 0x89, 0x53, - 0xb3, 0xf1, 0xcd, 0x02, 0x20, 0x85, 0xdb, 0x75, 0xa0, 0xca, 0x74, 0x8d, 0x07, 0x13, 0xa8, 0x72, - 0x07, 0x10, 0x33, 0x73, 0x09, 0x1c, 0x2f, 0xe4, 0x64, 0x5d, 0x21, 0x7b, 0x3e, 0x9c, 0x0d, 0xcd, - 0xb4, 0xf4, 0x5c, 0xbd, 0x9e, 0xa2, 0x86, 0x33, 0x5a, 0xd0, 0xcc, 0x97, 0x7a, 0xbb, 0x35, 0x5f, - 0xea, 0xeb, 0xe0, 0x82, 0xfd, 0x35, 0x0b, 0x46, 0xd4, 0x30, 0xbd, 0x4f, 0x5c, 0x40, 0x54, 0x7f, - 0x72, 0xee, 0x95, 0xb2, 0xd6, 0x65, 0xc6, 0x0c, 0x7c, 0x1f, 0x73, 0xa5, 0x77, 0xea, 0xee, 0x3d, - 0xa2, 0xe2, 0x29, 0x97, 0x84, 0x6b, 0xbc, 0x28, 0x3d, 0xd8, 0x2b, 0x8d, 0xa8, 0x7f, 0x3c, 0x82, - 0x6b, 0x5c, 0xc5, 0xfe, 0x25, 0xba, 0xd9, 0xcd, 0xa5, 0x88, 0x5e, 0x82, 0xde, 0xe6, 0x96, 0x13, - 0x92, 0x84, 0xab, 0x5c, 0x6f, 0x99, 0x16, 0x1e, 0xec, 0x95, 0x46, 0x55, 0x05, 0x56, 0x82, 0x39, - 0x76, 0xf7, 0xe1, 0x3f, 0xd3, 0x8b, 0xb3, 0x63, 0xf8, 0xcf, 0x7f, 0xb2, 0xa0, 0x67, 0x95, 0xde, - 0x5e, 0x0f, 0xff, 0x08, 0x78, 0xdd, 0x38, 0x02, 0x4e, 0xe7, 0x65, 0x16, 0xca, 0xdd, 0xfd, 0x4b, - 0x89, 0xdd, 0x7f, 0x36, 0x97, 0x42, 0xfb, 0x8d, 0xdf, 0x80, 0x21, 0x96, 0xaf, 0x48, 0xb8, 0x05, - 0xbe, 0x60, 0x6c, 0xf8, 0x52, 0x62, 0xc3, 0x8f, 0x69, 0xa8, 0xda, 0x4e, 0x7f, 0x0a, 0xfa, 0x85, - 0x9f, 0x59, 0x32, 0x22, 0x81, 0xc0, 0xc5, 0x12, 0x6e, 0xff, 0x7c, 0x11, 0x8c, 0xfc, 0x48, 0xe8, - 0xf7, 0x2d, 0x98, 0x09, 0xb8, 0xfd, 0x79, 0x6d, 0xa1, 0x15, 0xb8, 0xde, 0x66, 0xa5, 0xba, 0x45, - 0x6a, 0xad, 0xba, 0xeb, 0x6d, 0x2e, 0x6f, 0x7a, 0xbe, 0x2a, 0x5e, 0xbc, 0x4b, 0xaa, 0x2d, 0xa6, - 0x1b, 0xee, 0x90, 0x8c, 0x49, 0xf9, 0x71, 0x3c, 0xbf, 0xbf, 0x57, 0x9a, 0xc1, 0x87, 0xa2, 0x8d, - 0x0f, 0xd9, 0x17, 0xf4, 0xe7, 0x16, 0x5c, 0xe4, 0x79, 0x7a, 0xba, 0xef, 0x7f, 0x1b, 0x09, 0x47, - 0x59, 0x92, 0x8a, 0x89, 0xac, 0x91, 0xa0, 0x31, 0xf7, 0xb2, 0x18, 0xd0, 0x8b, 0xe5, 0xc3, 0xb5, - 0x85, 0x0f, 0xdb, 0x39, 0xfb, 0x7f, 0x2e, 0xc2, 0x88, 0x08, 0x13, 0x29, 0xee, 0x80, 0x97, 0x8c, - 0x25, 0xf1, 0x68, 0x62, 0x49, 0x4c, 0x18, 0xc8, 0x0f, 0xe6, 0xf8, 0x0f, 0x61, 0x82, 0x1e, 0xce, - 0x57, 0x89, 0x13, 0x44, 0xb7, 0x89, 0xc3, 0xad, 0x12, 0x8b, 0x87, 0x3e, 0xfd, 0x95, 0x78, 0xfc, - 0x7a, 0x92, 0x18, 0x4e, 0xd3, 0xff, 0x5e, 0xba, 0x73, 0x3c, 0x18, 0x4f, 0x45, 0xfa, 0x7c, 0x1b, - 0x06, 0x95, 0x93, 0x94, 0x38, 0x74, 0xda, 0x07, 0xcc, 0x4d, 0x52, 0xe0, 0x42, 0xcf, 0xd8, 0x41, - 0x2f, 0x26, 0x67, 0xff, 0x66, 0xc1, 0x68, 0x90, 0x4f, 0xe2, 0x2a, 0x0c, 0x38, 0x21, 0x0b, 0xe2, - 0x5d, 0x6b, 0x27, 0x97, 0x4e, 0x35, 0xc3, 0x1c, 0xd5, 0x66, 0x45, 0x4d, 0xac, 0x68, 0xa0, 0xab, - 0xdc, 0xf6, 0x73, 0x87, 0xb4, 0x13, 0x4a, 0xa7, 0xa8, 0x81, 0xb4, 0x0e, 0xdd, 0x21, 0x58, 0xd4, - 0x47, 0x9f, 0xe2, 0xc6, 0xb9, 0xd7, 0x3c, 0xff, 0x8e, 0x77, 0xc5, 0xf7, 0x65, 0x48, 0xa0, 0xee, - 0x08, 0x4e, 0x48, 0x93, 0x5c, 0x55, 0x1d, 0x9b, 0xd4, 0xba, 0x0b, 0x9d, 0xfd, 0x39, 0x60, 0x79, - 0x49, 0xcc, 0x98, 0x04, 0x21, 0x22, 0x30, 0x26, 0x62, 0x90, 0xca, 0x32, 0x31, 0x76, 0x99, 0xcf, - 0x6f, 0xb3, 0x76, 0xac, 0xc7, 0xb9, 0x66, 0x92, 0xc0, 0x49, 0x9a, 0xf6, 0x16, 0x3f, 0x84, 0x97, - 0x88, 0x13, 0xb5, 0x02, 0x12, 0xa2, 0x8f, 0xc3, 0x54, 0xfa, 0x65, 0x2c, 0xd4, 0x21, 0x16, 0xe3, - 0x9e, 0x4f, 0xef, 0xef, 0x95, 0xa6, 0x2a, 0x39, 0x38, 0x38, 0xb7, 0xb6, 0xfd, 0x2b, 0x16, 0x30, - 0x4f, 0xf0, 0x23, 0xe0, 0x7c, 0x3e, 0x66, 0x72, 0x3e, 0x53, 0x79, 0xd3, 0x99, 0xc3, 0xf4, 0xbc, - 0xc8, 0xd7, 0x70, 0x39, 0xf0, 0xef, 0xee, 0x0a, 0xdb, 0xad, 0xce, 0xcf, 0x38, 0xfb, 0xcb, 0x16, - 0xb0, 0x24, 0x3e, 0x98, 0xbf, 0xda, 0xa5, 0x82, 0xa3, 0xb3, 0x59, 0xc2, 0xc7, 0x61, 0x60, 0x43, - 0x0c, 0x7f, 0x86, 0xd0, 0xc9, 0xe8, 0xb0, 0x49, 0x5b, 0x4e, 0x9a, 0xf0, 0xe8, 0x14, 0xff, 0xb0, - 0xa2, 0x66, 0xff, 0xf7, 0x16, 0x4c, 0xe7, 0x57, 0x43, 0xeb, 0x70, 0x32, 0x20, 0xd5, 0x56, 0x10, - 0xd2, 0x2d, 0x21, 0x1e, 0x40, 0xc2, 0x29, 0x8a, 0x4f, 0xf5, 0x23, 0xfb, 0x7b, 0xa5, 0x93, 0x38, - 0x1b, 0x05, 0xe7, 0xd5, 0x45, 0xaf, 0xc0, 0x68, 0x2b, 0xe4, 0x9c, 0x1f, 0x63, 0xba, 0x42, 0x11, - 0x29, 0x9a, 0xf9, 0x0d, 0xad, 0x1b, 0x10, 0x9c, 0xc0, 0xb4, 0x7f, 0x80, 0x2f, 0x47, 0x15, 0x2c, - 0xba, 0x01, 0x13, 0x9e, 0xf6, 0x9f, 0xde, 0x80, 0xf2, 0xa9, 0xff, 0x78, 0xa7, 0x5b, 0x9f, 0x5d, - 0x97, 0x9a, 0xaf, 0x7a, 0x82, 0x0c, 0x4e, 0x53, 0xb6, 0x7f, 0xc1, 0x82, 0x93, 0x3a, 0xa2, 0xe6, - 0x0e, 0xd7, 0x49, 0x97, 0xb7, 0x00, 0x03, 0x7e, 0x93, 0x04, 0x4e, 0xe4, 0x07, 0xe2, 0x9a, 0xbb, - 0x20, 0x57, 0xe8, 0x0d, 0x51, 0x7e, 0x20, 0x92, 0xd7, 0x48, 0xea, 0xb2, 0x1c, 0xab, 0x9a, 0xc8, - 0x86, 0x3e, 0x26, 0x40, 0x0c, 0x85, 0xe3, 0x23, 0x3b, 0xb4, 0x98, 0x7d, 0x4a, 0x88, 0x05, 0xc4, - 0xfe, 0x7b, 0x8b, 0xaf, 0x4f, 0xbd, 0xeb, 0xe8, 0x5d, 0x18, 0x6f, 0x38, 0x51, 0x75, 0x6b, 0xf1, - 0x6e, 0x33, 0xe0, 0x2a, 0x5a, 0x39, 0x4e, 0xcf, 0x74, 0x1a, 0x27, 0xed, 0x23, 0x63, 0x03, 0xe9, - 0x95, 0x04, 0x31, 0x9c, 0x22, 0x8f, 0x6e, 0xc3, 0x10, 0x2b, 0x63, 0x3e, 0xbd, 0x61, 0x3b, 0x5e, - 0x26, 0xaf, 0x35, 0x65, 0xe2, 0xb3, 0x12, 0xd3, 0xc1, 0x3a, 0x51, 0xfb, 0xab, 0x45, 0x7e, 0x68, - 0xb0, 0xb7, 0xc7, 0x53, 0xd0, 0xdf, 0xf4, 0x6b, 0xf3, 0xcb, 0x0b, 0x58, 0xcc, 0x82, 0xba, 0xf7, - 0xca, 0xbc, 0x18, 0x4b, 0x38, 0xba, 0x00, 0x03, 0xe2, 0xa7, 0x54, 0xa9, 0xb3, 0x3d, 0x22, 0xf0, - 0x42, 0xac, 0xa0, 0xe8, 0x79, 0x80, 0x66, 0xe0, 0xef, 0xb8, 0x35, 0x16, 0x89, 0xa9, 0x68, 0x5a, - 0xe7, 0x95, 0x15, 0x04, 0x6b, 0x58, 0xe8, 0x55, 0x18, 0x69, 0x79, 0x21, 0xe7, 0x9f, 0xb4, 0x78, - 0xf7, 0xca, 0x6e, 0x6c, 0x5d, 0x07, 0x62, 0x13, 0x17, 0xcd, 0x42, 0x5f, 0xe4, 0x30, 0x6b, 0xb3, - 0xde, 0x7c, 0x23, 0xfa, 0x35, 0x8a, 0xa1, 0x67, 0x96, 0xa3, 0x15, 0xb0, 0xa8, 0x88, 0xde, 0x96, - 0xee, 0xf5, 0xfc, 0x26, 0x12, 0xde, 0x2b, 0xdd, 0xdd, 0x5a, 0x9a, 0x73, 0xbd, 0xf0, 0x8a, 0x31, - 0x68, 0xa1, 0x57, 0x00, 0xc8, 0xdd, 0x88, 0x04, 0x9e, 0x53, 0x57, 0x36, 0xa2, 0x8a, 0x91, 0x59, - 0xf0, 0x57, 0xfd, 0x68, 0x3d, 0x24, 0x8b, 0x0a, 0x03, 0x6b, 0xd8, 0xf6, 0x8f, 0x0e, 0x01, 0xc4, - 0x0f, 0x0d, 0x74, 0x0f, 0x06, 0xaa, 0x4e, 0xd3, 0xa9, 0xf2, 0xb4, 0xa9, 0xc5, 0x3c, 0xaf, 0xe7, - 0xb8, 0xc6, 0xcc, 0xbc, 0x40, 0xe7, 0xca, 0x1b, 0x19, 0x32, 0x7c, 0x40, 0x16, 0x77, 0x54, 0xd8, - 0xa8, 0xf6, 0xd0, 0x17, 0x2c, 0x18, 0x12, 0x91, 0x8e, 0xd8, 0x0c, 0x15, 0xf2, 0xf5, 0x6d, 0x5a, - 0xfb, 0xb3, 0x71, 0x0d, 0xde, 0x85, 0x17, 0xe4, 0x0a, 0xd5, 0x20, 0x1d, 0x7b, 0xa1, 0x37, 0x8c, - 0x3e, 0x2c, 0xdf, 0xb6, 0x45, 0x63, 0x28, 0xd5, 0xdb, 0x76, 0x90, 0x5d, 0x35, 0xfa, 0xb3, 0x76, - 0xdd, 0x78, 0xd6, 0xf6, 0xe4, 0xfb, 0x0f, 0x1b, 0xfc, 0x76, 0xa7, 0x17, 0x2d, 0x2a, 0xeb, 0xb1, - 0x44, 0x7a, 0xf3, 0x9d, 0x5e, 0xb5, 0x87, 0x5d, 0x87, 0x38, 0x22, 0x9f, 0x85, 0xb1, 0x9a, 0xc9, - 0xb5, 0x88, 0x95, 0xf8, 0x64, 0x1e, 0xdd, 0x04, 0x93, 0x13, 0xf3, 0x29, 0x09, 0x00, 0x4e, 0x12, - 0x46, 0x65, 0x1e, 0x5a, 0x66, 0xd9, 0xdb, 0xf0, 0x85, 0x07, 0x95, 0x9d, 0x3b, 0x97, 0xbb, 0x61, - 0x44, 0x1a, 0x14, 0x33, 0x66, 0x12, 0x56, 0x45, 0x5d, 0xac, 0xa8, 0xa0, 0x37, 0xa1, 0x8f, 0x79, - 0x3d, 0x86, 0x53, 0x03, 0xf9, 0x6a, 0x0d, 0x33, 0x12, 0x6a, 0xbc, 0x21, 0xd9, 0xdf, 0x10, 0x0b, - 0x0a, 0xe8, 0xaa, 0xf4, 0x29, 0x0e, 0x97, 0xbd, 0xf5, 0x90, 0x30, 0x9f, 0xe2, 0xc1, 0xb9, 0xc7, - 0x63, 0x77, 0x61, 0x5e, 0x9e, 0x99, 0x7f, 0xd6, 0xa8, 0x49, 0xd9, 0x3e, 0xf1, 0x5f, 0xa6, 0xb5, - 0x15, 0x71, 0xdb, 0x32, 0xbb, 0x67, 0xa6, 0xbe, 0x8d, 0x87, 0xf3, 0xa6, 0x49, 0x02, 0x27, 0x69, - 0x52, 0x16, 0x9a, 0xef, 0x7a, 0xe1, 0x83, 0xd5, 0xe9, 0xec, 0xe0, 0x92, 0x03, 0x76, 0x1b, 0xf1, - 0x12, 0x2c, 0xea, 0x23, 0x17, 0xc6, 0x02, 0x83, 0xbd, 0x90, 0xe1, 0xd6, 0xce, 0x77, 0xc7, 0xc4, - 0x68, 0x81, 0xfc, 0x4d, 0x32, 0x38, 0x49, 0x17, 0xbd, 0xa9, 0x31, 0x4a, 0x23, 0xed, 0x5f, 0xfe, - 0x9d, 0x58, 0xa3, 0xe9, 0x6d, 0x18, 0x31, 0x0e, 0x9b, 0x87, 0xaa, 0x82, 0xf4, 0x60, 0x3c, 0x79, - 0xb2, 0x3c, 0x54, 0xcd, 0xe3, 0xdf, 0xf6, 0xc0, 0xa8, 0xb9, 0x13, 0xd0, 0x45, 0x18, 0x14, 0x44, - 0x54, 0x46, 0x2b, 0xb5, 0xb9, 0x57, 0x24, 0x00, 0xc7, 0x38, 0x2c, 0x91, 0x19, 0xab, 0xae, 0xf9, - 0x0a, 0xc4, 0x89, 0xcc, 0x14, 0x04, 0x6b, 0x58, 0xf4, 0x01, 0x7b, 0xdb, 0xf7, 0x23, 0x75, 0x8f, - 0xaa, 0xed, 0x32, 0xc7, 0x4a, 0xb1, 0x80, 0xd2, 0xfb, 0x73, 0x9b, 0x04, 0x1e, 0xa9, 0x9b, 0x29, - 0x1d, 0xd4, 0xfd, 0x79, 0x4d, 0x07, 0x62, 0x13, 0x97, 0x72, 0x01, 0x7e, 0xc8, 0xf6, 0x9f, 0x78, - 0x26, 0xc7, 0xbe, 0x17, 0x15, 0x1e, 0x45, 0x42, 0xc2, 0xd1, 0x27, 0xe0, 0xa4, 0x0a, 0x9f, 0x28, - 0x56, 0x97, 0x6c, 0xb1, 0xcf, 0x90, 0x6a, 0x9d, 0x9c, 0xcf, 0x46, 0xc3, 0x79, 0xf5, 0xd1, 0xeb, - 0x30, 0x2a, 0x9e, 0x52, 0x92, 0x62, 0xbf, 0x69, 0x48, 0x78, 0xcd, 0x80, 0xe2, 0x04, 0xb6, 0x4c, - 0x4a, 0xc1, 0xde, 0x18, 0x92, 0xc2, 0x40, 0x3a, 0x29, 0x85, 0x0e, 0xc7, 0xa9, 0x1a, 0x68, 0x16, - 0xc6, 0x38, 0xeb, 0xe8, 0x7a, 0x9b, 0x7c, 0x4e, 0x84, 0x67, 0xa7, 0xda, 0x54, 0x37, 0x4c, 0x30, - 0x4e, 0xe2, 0xa3, 0xcb, 0x30, 0xec, 0x04, 0xd5, 0x2d, 0x37, 0x22, 0x55, 0xba, 0x33, 0x98, 0x2d, - 0x9f, 0x66, 0x89, 0x39, 0xab, 0xc1, 0xb0, 0x81, 0x69, 0xdf, 0x83, 0xc9, 0x8c, 0xf0, 0x32, 0x74, - 0xe1, 0x38, 0x4d, 0x57, 0x7e, 0x53, 0xc2, 0xdd, 0x61, 0xb6, 0xbc, 0x2c, 0xbf, 0x46, 0xc3, 0xa2, - 0xab, 0x93, 0x85, 0xa1, 0xd1, 0x92, 0x6f, 0xab, 0xd5, 0xb9, 0x24, 0x01, 0x38, 0xc6, 0xb1, 0xff, - 0xb9, 0x00, 0x63, 0x19, 0x0a, 0x3a, 0x96, 0x00, 0x3a, 0xf1, 0xd2, 0x8a, 0xf3, 0x3d, 0x9b, 0x39, - 0x4e, 0x0a, 0x87, 0xc8, 0x71, 0x52, 0xec, 0x94, 0xe3, 0xa4, 0xe7, 0xbd, 0xe4, 0x38, 0x31, 0x47, - 0xac, 0xb7, 0xab, 0x11, 0xcb, 0xc8, 0x8b, 0xd2, 0x77, 0xc8, 0xbc, 0x28, 0xc6, 0xa0, 0xf7, 0x77, - 0x31, 0xe8, 0x3f, 0x5d, 0x80, 0xf1, 0xa4, 0x6e, 0xef, 0x08, 0xe4, 0xe3, 0x6f, 0x1a, 0xf2, 0xf1, - 0x0b, 0xdd, 0x78, 0xe2, 0xe7, 0xca, 0xca, 0x71, 0x42, 0x56, 0xfe, 0x74, 0x57, 0xd4, 0xda, 0xcb, - 0xcd, 0x7f, 0xb1, 0x00, 0xc7, 0x33, 0x55, 0x9e, 0x47, 0x30, 0x36, 0x37, 0x8c, 0xb1, 0x79, 0xae, - 0xeb, 0x28, 0x05, 0xb9, 0x03, 0x74, 0x2b, 0x31, 0x40, 0x17, 0xbb, 0x27, 0xd9, 0x7e, 0x94, 0xbe, - 0x55, 0x84, 0xb3, 0x99, 0xf5, 0x62, 0xf1, 0xf2, 0x92, 0x21, 0x5e, 0x7e, 0x3e, 0x21, 0x5e, 0xb6, - 0xdb, 0xd7, 0x7e, 0x30, 0xf2, 0x66, 0xe1, 0xad, 0xcf, 0x62, 0x8e, 0xdc, 0xa7, 0xac, 0xd9, 0xf0, - 0xd6, 0x57, 0x84, 0xb0, 0x49, 0xf7, 0x7b, 0x49, 0xc6, 0xfc, 0x67, 0x16, 0x9c, 0xca, 0x9c, 0x9b, - 0x23, 0x90, 0xf4, 0xad, 0x9a, 0x92, 0xbe, 0xa7, 0xba, 0x5e, 0xad, 0x39, 0xa2, 0xbf, 0x2f, 0xf6, - 0xe5, 0x7c, 0x0b, 0x13, 0x40, 0xdc, 0x80, 0x21, 0xa7, 0x5a, 0x25, 0x61, 0xb8, 0xe2, 0xd7, 0x54, - 0x3a, 0x84, 0xe7, 0xd8, 0xf3, 0x30, 0x2e, 0x3e, 0xd8, 0x2b, 0x4d, 0x27, 0x49, 0xc4, 0x60, 0xac, - 0x53, 0x40, 0x9f, 0x82, 0x81, 0x50, 0x66, 0xb2, 0xec, 0xb9, 0xff, 0x4c, 0x96, 0x8c, 0xc9, 0x55, - 0x02, 0x16, 0x45, 0x12, 0x7d, 0xbf, 0x1e, 0xfd, 0xa9, 0x8d, 0x68, 0x91, 0x77, 0xf2, 0x3e, 0x62, - 0x40, 0x3d, 0x0f, 0xb0, 0xa3, 0x5e, 0x32, 0x49, 0xe1, 0x89, 0xf6, 0xc6, 0xd1, 0xb0, 0xd0, 0x1b, - 0x30, 0x1e, 0xf2, 0xc0, 0xa7, 0xb1, 0x91, 0x0a, 0x5f, 0x8b, 0x2c, 0x76, 0x5c, 0x25, 0x01, 0xc3, - 0x29, 0x6c, 0xb4, 0x24, 0x5b, 0x65, 0xe6, 0x48, 0x7c, 0x79, 0x9e, 0x8f, 0x5b, 0x14, 0x26, 0x49, - 0xc7, 0x92, 0x93, 0xc0, 0x86, 0x5f, 0xab, 0x89, 0x3e, 0x05, 0x40, 0x17, 0x91, 0x10, 0xa2, 0xf4, - 0xe7, 0x1f, 0xa1, 0xf4, 0x6c, 0xa9, 0x65, 0x7a, 0x32, 0x30, 0x37, 0xfb, 0x05, 0x45, 0x04, 0x6b, - 0x04, 0x91, 0x03, 0x23, 0xf1, 0xbf, 0x38, 0x47, 0xfb, 0x85, 0xdc, 0x16, 0x92, 0xc4, 0x99, 0x82, - 0x61, 0x41, 0x27, 0x81, 0x4d, 0x8a, 0xe8, 0x93, 0x70, 0x6a, 0x27, 0xd7, 0xf2, 0x87, 0x73, 0x82, - 0x2c, 0xe9, 0x7a, 0xbe, 0xbd, 0x4f, 0x7e, 0x7d, 0xfb, 0x7f, 0x07, 0x78, 0xa4, 0xcd, 0x49, 0x8f, - 0x66, 0x4d, 0xad, 0xfd, 0x33, 0x49, 0xc9, 0xc6, 0x74, 0x66, 0x65, 0x43, 0xd4, 0x91, 0xd8, 0x50, - 0x85, 0xf7, 0xbc, 0xa1, 0x7e, 0xc2, 0xd2, 0x64, 0x4e, 0xdc, 0xa6, 0xfb, 0x63, 0x87, 0xbc, 0xc1, - 0x1e, 0xa0, 0x10, 0x6a, 0x23, 0x43, 0x92, 0xf3, 0x7c, 0xd7, 0xdd, 0xe9, 0x5e, 0xb4, 0xf3, 0xf5, - 0xec, 0x80, 0xef, 0x5c, 0xc8, 0x73, 0xe5, 0xb0, 0xdf, 0x7f, 0x54, 0xc1, 0xdf, 0xbf, 0x69, 0xc1, - 0xa9, 0x54, 0x31, 0xef, 0x03, 0x09, 0x45, 0xb4, 0xbb, 0xd5, 0xf7, 0xdc, 0x79, 0x49, 0x90, 0x7f, - 0xc3, 0x55, 0xf1, 0x0d, 0xa7, 0x72, 0xf1, 0x92, 0x5d, 0xff, 0xd2, 0xdf, 0x94, 0x26, 0x59, 0x03, - 0x26, 0x22, 0xce, 0xef, 0x3a, 0x6a, 0xc2, 0xb9, 0x6a, 0x2b, 0x08, 0xe2, 0xc5, 0x9a, 0xb1, 0x39, - 0xf9, 0x5b, 0xef, 0xf1, 0xfd, 0xbd, 0xd2, 0xb9, 0xf9, 0x0e, 0xb8, 0xb8, 0x23, 0x35, 0xe4, 0x01, - 0x6a, 0xa4, 0xec, 0xeb, 0xd8, 0x01, 0x90, 0x23, 0x87, 0x49, 0x5b, 0xe3, 0x71, 0x4b, 0xd9, 0x0c, - 0x2b, 0xbd, 0x0c, 0xca, 0x47, 0x2b, 0x3d, 0xf9, 0xce, 0xc4, 0xa5, 0x9f, 0xbe, 0x0e, 0x67, 0xdb, - 0x2f, 0xa6, 0x43, 0x85, 0x72, 0xf8, 0x4b, 0x0b, 0xce, 0xb4, 0x8d, 0x17, 0xf6, 0x5d, 0xf8, 0x58, - 0xb0, 0x3f, 0x6f, 0xc1, 0xa3, 0x99, 0x35, 0x92, 0x4e, 0x78, 0x55, 0x5a, 0xa8, 0x99, 0xa3, 0xc6, - 0x91, 0x73, 0x24, 0x00, 0xc7, 0x38, 0x86, 0xc5, 0x66, 0xa1, 0xa3, 0xc5, 0xe6, 0x1f, 0x59, 0x90, - 0xba, 0xea, 0x8f, 0x80, 0xf3, 0x5c, 0x36, 0x39, 0xcf, 0xc7, 0xbb, 0x19, 0xcd, 0x1c, 0xa6, 0xf3, - 0x1f, 0xc7, 0xe0, 0x44, 0x8e, 0x27, 0xf6, 0x0e, 0x4c, 0x6c, 0x56, 0x89, 0x19, 0x7a, 0xa3, 0x5d, - 0x48, 0xba, 0xb6, 0x71, 0x3a, 0xe6, 0x8e, 0xef, 0xef, 0x95, 0x26, 0x52, 0x28, 0x38, 0xdd, 0x04, - 0xfa, 0xbc, 0x05, 0xc7, 0x9c, 0x3b, 0xe1, 0x22, 0x7d, 0x41, 0xb8, 0xd5, 0xb9, 0xba, 0x5f, 0xdd, - 0xa6, 0x8c, 0x99, 0xdc, 0x56, 0x2f, 0x66, 0x0a, 0xa3, 0x6f, 0x55, 0x52, 0xf8, 0x46, 0xf3, 0x53, - 0xfb, 0x7b, 0xa5, 0x63, 0x59, 0x58, 0x38, 0xb3, 0x2d, 0x84, 0x45, 0xc6, 0x2f, 0x27, 0xda, 0x6a, - 0x17, 0x1c, 0x26, 0xcb, 0x65, 0x9e, 0xb3, 0xc4, 0x12, 0x82, 0x15, 0x1d, 0xf4, 0x19, 0x18, 0xdc, - 0x94, 0x71, 0x20, 0x32, 0x58, 0xee, 0x78, 0x20, 0xdb, 0x47, 0xc7, 0xe0, 0x26, 0x30, 0x0a, 0x09, - 0xc7, 0x44, 0xd1, 0xeb, 0x50, 0xf4, 0x36, 0x42, 0x11, 0xa2, 0x2e, 0xdb, 0x12, 0xd7, 0xb4, 0x75, - 0xe6, 0x21, 0x98, 0x56, 0x97, 0x2a, 0x98, 0x56, 0x44, 0x57, 0xa1, 0x18, 0xdc, 0xae, 0x09, 0x4d, - 0x4a, 0xe6, 0x26, 0xc5, 0x73, 0x0b, 0x39, 0xbd, 0x62, 0x94, 0xf0, 0xdc, 0x02, 0xa6, 0x24, 0x50, - 0x19, 0x7a, 0x99, 0xfb, 0xb2, 0x60, 0x6d, 0x33, 0x9f, 0xf2, 0x6d, 0xc2, 0x00, 0x70, 0x8f, 0x44, - 0x86, 0x80, 0x39, 0x21, 0xb4, 0x06, 0x7d, 0x55, 0xd7, 0xab, 0x91, 0x40, 0xf0, 0xb2, 0x1f, 0xce, - 0xd4, 0x99, 0x30, 0x8c, 0x1c, 0x9a, 0x5c, 0x85, 0xc0, 0x30, 0xb0, 0xa0, 0xc5, 0xa8, 0x92, 0xe6, - 0xd6, 0x86, 0xbc, 0xb1, 0xb2, 0xa9, 0x92, 0xe6, 0xd6, 0x52, 0xa5, 0x2d, 0x55, 0x86, 0x81, 0x05, - 0x2d, 0xf4, 0x0a, 0x14, 0x36, 0xaa, 0xc2, 0x35, 0x39, 0x53, 0x79, 0x62, 0x46, 0xd1, 0x9a, 0xeb, - 0xdb, 0xdf, 0x2b, 0x15, 0x96, 0xe6, 0x71, 0x61, 0xa3, 0x8a, 0x56, 0xa1, 0x7f, 0x83, 0xc7, 0xdd, - 0x11, 0xfa, 0x91, 0x27, 0xb3, 0x43, 0x02, 0xa5, 0x42, 0xf3, 0x70, 0xef, 0x52, 0x01, 0xc0, 0x92, - 0x08, 0x4b, 0x40, 0xa5, 0xe2, 0x07, 0x89, 0xf0, 0xa5, 0x33, 0x87, 0x8b, 0xf9, 0xc4, 0x9f, 0x1a, - 0x71, 0x14, 0x22, 0xac, 0x51, 0xa4, 0xab, 0xda, 0xb9, 0xd7, 0x0a, 0x58, 0x6e, 0x0b, 0xa1, 0x1a, - 0xc9, 0x5c, 0xd5, 0xb3, 0x12, 0xa9, 0xdd, 0xaa, 0x56, 0x48, 0x38, 0x26, 0x8a, 0xb6, 0x61, 0x64, - 0x27, 0x6c, 0x6e, 0x11, 0xb9, 0xa5, 0x59, 0xd8, 0xbb, 0x1c, 0x6e, 0xf6, 0xa6, 0x40, 0x74, 0x83, - 0xa8, 0xe5, 0xd4, 0x53, 0xa7, 0x10, 0x7b, 0xd6, 0xdc, 0xd4, 0x89, 0x61, 0x93, 0x36, 0x1d, 0xfe, - 0x77, 0x5b, 0xfe, 0xed, 0xdd, 0x88, 0x88, 0xa8, 0xa3, 0x99, 0xc3, 0xff, 0x16, 0x47, 0x49, 0x0f, - 0xbf, 0x00, 0x60, 0x49, 0x04, 0xdd, 0x14, 0xc3, 0xc3, 0x4e, 0xcf, 0xf1, 0xfc, 0x90, 0xe6, 0xb3, - 0x12, 0x29, 0x67, 0x50, 0xd8, 0x69, 0x19, 0x93, 0x62, 0xa7, 0x64, 0x73, 0xcb, 0x8f, 0x7c, 0x2f, - 0x71, 0x42, 0x4f, 0xe4, 0x9f, 0x92, 0xe5, 0x0c, 0xfc, 0xf4, 0x29, 0x99, 0x85, 0x85, 0x33, 0xdb, - 0x42, 0x35, 0x18, 0x6d, 0xfa, 0x41, 0x74, 0xc7, 0x0f, 0xe4, 0xfa, 0x42, 0x6d, 0x04, 0xa5, 0x06, - 0xa6, 0x68, 0x91, 0x19, 0xe6, 0x98, 0x10, 0x9c, 0xa0, 0x89, 0x3e, 0x0e, 0xfd, 0x61, 0xd5, 0xa9, - 0x93, 0xe5, 0x1b, 0x53, 0x93, 0xf9, 0xd7, 0x4f, 0x85, 0xa3, 0xe4, 0xac, 0x2e, 0x1e, 0x36, 0x89, - 0xa3, 0x60, 0x49, 0x0e, 0x2d, 0x41, 0x2f, 0x4b, 0xec, 0xcc, 0x42, 0xe4, 0xe6, 0x44, 0x66, 0x4f, - 0xb9, 0xd5, 0xf0, 0xb3, 0x89, 0x15, 0x63, 0x5e, 0x9d, 0xee, 0x01, 0x21, 0x29, 0xf0, 0xc3, 0xa9, - 0xe3, 0xf9, 0x7b, 0x40, 0x08, 0x18, 0x6e, 0x54, 0xda, 0xed, 0x01, 0x85, 0x84, 0x63, 0xa2, 0xf4, - 0x64, 0xa6, 0xa7, 0xe9, 0x89, 0x36, 0x26, 0x93, 0xb9, 0x67, 0x29, 0x3b, 0x99, 0xe9, 0x49, 0x4a, - 0x49, 0xd8, 0x7f, 0x30, 0x90, 0xe6, 0x59, 0x98, 0x84, 0xe9, 0x3f, 0xb7, 0x52, 0x36, 0x13, 0x1f, - 0xe9, 0x56, 0xe0, 0xfd, 0x00, 0x1f, 0xae, 0x9f, 0xb7, 0xe0, 0x44, 0x33, 0xf3, 0x43, 0x04, 0x03, - 0xd0, 0x9d, 0xdc, 0x9c, 0x7f, 0xba, 0x0a, 0xa7, 0x9c, 0x0d, 0xc7, 0x39, 0x2d, 0x25, 0x85, 0x03, - 0xc5, 0xf7, 0x2c, 0x1c, 0x58, 0x81, 0x81, 0x2a, 0x7f, 0xc9, 0xc9, 0x34, 0x00, 0x5d, 0x05, 0x03, - 0x65, 0xac, 0x84, 0x78, 0x02, 0x6e, 0x60, 0x45, 0x02, 0xfd, 0xa4, 0x05, 0x67, 0x92, 0x5d, 0xc7, - 0x84, 0x81, 0x85, 0xc1, 0x24, 0x17, 0x6b, 0x2d, 0x89, 0xef, 0x4f, 0xf1, 0xff, 0x06, 0xf2, 0x41, - 0x27, 0x04, 0xdc, 0xbe, 0x31, 0xb4, 0x90, 0x21, 0x57, 0xeb, 0x33, 0x35, 0x8a, 0x5d, 0xc8, 0xd6, - 0x5e, 0x84, 0xe1, 0x86, 0xdf, 0xf2, 0x22, 0x61, 0xf7, 0x28, 0x8c, 0xa7, 0x98, 0xd1, 0xd0, 0x8a, - 0x56, 0x8e, 0x0d, 0xac, 0x84, 0x44, 0x6e, 0xe0, 0xbe, 0x25, 0x72, 0xef, 0xc0, 0xb0, 0xa7, 0xb9, - 0x04, 0xb4, 0x7b, 0xc1, 0x0a, 0xe9, 0xa2, 0x86, 0xcd, 0x7b, 0xa9, 0x97, 0x60, 0x83, 0x5a, 0x7b, - 0x69, 0x19, 0xbc, 0x37, 0x69, 0xd9, 0x91, 0x3e, 0x89, 0xed, 0x5f, 0x2f, 0x64, 0xbc, 0x18, 0xb8, - 0x54, 0xee, 0x35, 0x53, 0x2a, 0x77, 0x3e, 0x29, 0x95, 0x4b, 0xa9, 0xaa, 0x0c, 0x81, 0x5c, 0xf7, - 0x19, 0x25, 0xbb, 0x0e, 0xf0, 0xfc, 0xc3, 0x16, 0x9c, 0x64, 0xba, 0x0f, 0xda, 0xc0, 0x7b, 0xd6, - 0x77, 0x30, 0x93, 0xd4, 0xeb, 0xd9, 0xe4, 0x70, 0x5e, 0x3b, 0x76, 0x1d, 0xce, 0x75, 0xba, 0x77, - 0x99, 0x85, 0x6f, 0x4d, 0x19, 0x47, 0xc4, 0x16, 0xbe, 0xb5, 0xe5, 0x05, 0xcc, 0x20, 0xdd, 0x86, - 0x2f, 0xb4, 0xff, 0x7f, 0x0b, 0x8a, 0x65, 0xbf, 0x76, 0x04, 0x2f, 0xfa, 0x8f, 0x19, 0x2f, 0xfa, - 0x47, 0xb2, 0x6f, 0xfc, 0x5a, 0xae, 0xb2, 0x6f, 0x31, 0xa1, 0xec, 0x3b, 0x93, 0x47, 0xa0, 0xbd, - 0x6a, 0xef, 0x97, 0x8a, 0x30, 0x54, 0xf6, 0x6b, 0x6a, 0x9f, 0xfd, 0xaf, 0xf7, 0xe3, 0xc8, 0x93, - 0x9b, 0x7d, 0x4a, 0xa3, 0xcc, 0x2c, 0x7a, 0x65, 0xdc, 0x89, 0xef, 0x32, 0x7f, 0x9e, 0x5b, 0xc4, - 0xdd, 0xdc, 0x8a, 0x48, 0x2d, 0xf9, 0x39, 0x47, 0xe7, 0xcf, 0xf3, 0xed, 0x22, 0x8c, 0x25, 0x5a, - 0x47, 0x75, 0x18, 0xa9, 0xeb, 0xaa, 0x24, 0xb1, 0x4e, 0xef, 0x4b, 0x0b, 0x25, 0xfc, 0x21, 0xb4, - 0x22, 0x6c, 0x12, 0x47, 0x33, 0x00, 0x9e, 0x6e, 0x15, 0xae, 0x02, 0x15, 0x6b, 0x16, 0xe1, 0x1a, - 0x06, 0x7a, 0x09, 0x86, 0x22, 0xbf, 0xe9, 0xd7, 0xfd, 0xcd, 0xdd, 0x6b, 0x44, 0x46, 0xb6, 0x54, - 0x46, 0xc3, 0x6b, 0x31, 0x08, 0xeb, 0x78, 0xe8, 0x2e, 0x4c, 0x28, 0x22, 0x95, 0x07, 0xa0, 0x5e, - 0x63, 0x62, 0x93, 0xd5, 0x24, 0x45, 0x9c, 0x6e, 0x04, 0xbd, 0x02, 0xa3, 0xcc, 0x7a, 0x99, 0xd5, - 0xbf, 0x46, 0x76, 0x65, 0xc4, 0x63, 0xc6, 0x61, 0xaf, 0x18, 0x10, 0x9c, 0xc0, 0x44, 0xf3, 0x30, - 0xd1, 0x70, 0xc3, 0x44, 0xf5, 0x3e, 0x56, 0x9d, 0x75, 0x60, 0x25, 0x09, 0xc4, 0x69, 0x7c, 0xfb, - 0x57, 0xc5, 0x1c, 0x7b, 0x91, 0xfb, 0xc1, 0x76, 0x7c, 0x7f, 0x6f, 0xc7, 0x6f, 0x59, 0x30, 0x4e, - 0x5b, 0x67, 0x26, 0x99, 0x92, 0x91, 0x52, 0x39, 0x31, 0xac, 0x36, 0x39, 0x31, 0xce, 0xd3, 0x63, - 0xbb, 0xe6, 0xb7, 0x22, 0x21, 0x1d, 0xd5, 0xce, 0x65, 0x5a, 0x8a, 0x05, 0x54, 0xe0, 0x91, 0x20, - 0x10, 0x7e, 0xef, 0x3a, 0x1e, 0x09, 0x02, 0x2c, 0xa0, 0x32, 0x65, 0x46, 0x4f, 0x76, 0xca, 0x0c, - 0x1e, 0xf9, 0x5c, 0x58, 0xc1, 0x09, 0x96, 0x56, 0x8b, 0x7c, 0x2e, 0xcd, 0xe3, 0x62, 0x1c, 0xfb, - 0xeb, 0x45, 0x18, 0x2e, 0xfb, 0xb5, 0xd8, 0xb0, 0xe3, 0x45, 0xc3, 0xb0, 0xe3, 0x5c, 0xc2, 0xb0, - 0x63, 0x5c, 0xc7, 0xfd, 0xc0, 0x8c, 0xe3, 0x3b, 0x65, 0xc6, 0xf1, 0x87, 0x16, 0x9b, 0xb5, 0x85, - 0xd5, 0x0a, 0xb7, 0xf0, 0x45, 0x97, 0x60, 0x88, 0x9d, 0x70, 0x2c, 0xd0, 0x82, 0xb4, 0x76, 0x60, - 0x29, 0x2c, 0x57, 0xe3, 0x62, 0xac, 0xe3, 0xa0, 0x0b, 0x30, 0x10, 0x12, 0x27, 0xa8, 0x6e, 0xa9, - 0xe3, 0x5d, 0x98, 0x26, 0xf0, 0x32, 0xac, 0xa0, 0xe8, 0xad, 0x38, 0xe8, 0x76, 0x31, 0xdf, 0x5c, - 0x58, 0xef, 0x0f, 0xdf, 0x22, 0xf9, 0x91, 0xb6, 0xed, 0x5b, 0x80, 0xd2, 0xf8, 0x5d, 0xf8, 0x5f, - 0x95, 0xcc, 0xb0, 0xb0, 0x83, 0xa9, 0x90, 0xb0, 0xff, 0x62, 0xc1, 0x68, 0xd9, 0xaf, 0xd1, 0xad, - 0xfb, 0xbd, 0xb4, 0x4f, 0xf5, 0x8c, 0x03, 0x7d, 0x6d, 0x32, 0x0e, 0x3c, 0x06, 0xbd, 0x65, 0xbf, - 0xd6, 0x21, 0x74, 0xed, 0x7f, 0x63, 0x41, 0x7f, 0xd9, 0xaf, 0x1d, 0x81, 0xe2, 0xe5, 0x35, 0x53, - 0xf1, 0x72, 0x32, 0x67, 0xdd, 0xe4, 0xe8, 0x5a, 0xfe, 0xa4, 0x07, 0x46, 0x68, 0x3f, 0xfd, 0x4d, - 0x39, 0x95, 0xc6, 0xb0, 0x59, 0x5d, 0x0c, 0x1b, 0x7d, 0x06, 0xf8, 0xf5, 0xba, 0x7f, 0x27, 0x39, - 0xad, 0x4b, 0xac, 0x14, 0x0b, 0x28, 0x7a, 0x16, 0x06, 0x9a, 0x01, 0xd9, 0x71, 0x7d, 0xc1, 0x5f, - 0x6b, 0x6a, 0xac, 0xb2, 0x28, 0xc7, 0x0a, 0x83, 0x3e, 0xbc, 0x43, 0xd7, 0xa3, 0xbc, 0x44, 0xd5, - 0xf7, 0x6a, 0x5c, 0x37, 0x51, 0x14, 0x69, 0xb1, 0xb4, 0x72, 0x6c, 0x60, 0xa1, 0x5b, 0x30, 0xc8, - 0xfe, 0xb3, 0x63, 0xa7, 0xf7, 0xd0, 0xc7, 0x8e, 0x48, 0x14, 0x2c, 0x08, 0xe0, 0x98, 0x16, 0x7a, - 0x1e, 0x20, 0x92, 0xa9, 0x65, 0x42, 0x11, 0xc2, 0x54, 0xbd, 0x45, 0x54, 0xd2, 0x99, 0x10, 0x6b, - 0x58, 0xe8, 0x19, 0x18, 0x8c, 0x1c, 0xb7, 0x7e, 0xdd, 0xf5, 0x98, 0xfe, 0x9e, 0xf6, 0x5f, 0xe4, - 0xeb, 0x15, 0x85, 0x38, 0x86, 0x53, 0x5e, 0x90, 0xc5, 0x84, 0x9a, 0xdb, 0x8d, 0x44, 0x6a, 0xba, - 0x22, 0xe7, 0x05, 0xaf, 0xab, 0x52, 0xac, 0x61, 0xa0, 0x2d, 0x38, 0xed, 0x7a, 0x2c, 0x85, 0x14, - 0xa9, 0x6c, 0xbb, 0xcd, 0xb5, 0xeb, 0x95, 0x9b, 0x24, 0x70, 0x37, 0x76, 0xe7, 0x9c, 0xea, 0x36, - 0xf1, 0x64, 0x42, 0xfc, 0xc7, 0x45, 0x17, 0x4f, 0x2f, 0xb7, 0xc1, 0xc5, 0x6d, 0x29, 0x21, 0x9b, - 0x6e, 0xc7, 0x80, 0x38, 0x0d, 0x21, 0x13, 0xe0, 0xe9, 0x67, 0x58, 0x09, 0x16, 0x10, 0xfb, 0x05, - 0xb6, 0x27, 0x6e, 0x54, 0xd0, 0xd3, 0xc6, 0xf1, 0x72, 0x42, 0x3f, 0x5e, 0x0e, 0xf6, 0x4a, 0x7d, - 0x37, 0x2a, 0x5a, 0x7c, 0xa0, 0xcb, 0x70, 0xbc, 0xec, 0xd7, 0xca, 0x7e, 0x10, 0x2d, 0xf9, 0xc1, - 0x1d, 0x27, 0xa8, 0xc9, 0x25, 0x58, 0x92, 0x11, 0x92, 0xe8, 0x19, 0xdb, 0xcb, 0x4f, 0x20, 0x23, - 0xfa, 0xd1, 0x0b, 0x8c, 0xab, 0x3b, 0xa4, 0x43, 0x6a, 0x95, 0xf1, 0x17, 0x2a, 0x51, 0xdb, 0x15, - 0x27, 0x22, 0xe8, 0x06, 0x8c, 0x54, 0xf5, 0xab, 0x56, 0x54, 0x7f, 0x4a, 0x5e, 0x76, 0xc6, 0x3d, - 0x9c, 0x79, 0x37, 0x9b, 0xf5, 0xed, 0x6f, 0x5a, 0xa2, 0x15, 0x2e, 0xad, 0xe0, 0x76, 0xaf, 0x9d, - 0xcf, 0xdc, 0x79, 0x98, 0x08, 0xf4, 0x2a, 0x9a, 0xfd, 0xd8, 0x71, 0x9e, 0xf9, 0x26, 0x01, 0xc4, - 0x69, 0x7c, 0xf4, 0x49, 0x38, 0x65, 0x14, 0x4a, 0x55, 0xba, 0x96, 0x7f, 0x9a, 0xc9, 0x73, 0x70, - 0x1e, 0x12, 0xce, 0xaf, 0x6f, 0xff, 0x20, 0x9c, 0x48, 0x7e, 0x97, 0x90, 0xb0, 0xdc, 0xe7, 0xd7, - 0x15, 0x0e, 0xf7, 0x75, 0xf6, 0x4b, 0x30, 0x41, 0x9f, 0xde, 0x8a, 0x8d, 0x64, 0xf3, 0xd7, 0x39, - 0x08, 0xd5, 0x6f, 0x0e, 0xb0, 0x6b, 0x30, 0x91, 0x7d, 0x0d, 0x7d, 0x1a, 0x46, 0x43, 0xc2, 0x22, - 0xaf, 0x49, 0xc9, 0x5e, 0x1b, 0x6f, 0xf2, 0xca, 0xa2, 0x8e, 0xc9, 0x5f, 0x2f, 0x66, 0x19, 0x4e, - 0x50, 0x43, 0x0d, 0x18, 0xbd, 0xe3, 0x7a, 0x35, 0xff, 0x4e, 0x28, 0xe9, 0x0f, 0xe4, 0xab, 0x09, - 0x6e, 0x71, 0xcc, 0x44, 0x1f, 0x8d, 0xe6, 0x6e, 0x19, 0xc4, 0x70, 0x82, 0x38, 0x3d, 0x6a, 0x82, - 0x96, 0x37, 0x1b, 0xae, 0x87, 0x24, 0x10, 0x71, 0xe1, 0xd8, 0x51, 0x83, 0x65, 0x21, 0x8e, 0xe1, - 0xf4, 0xa8, 0x61, 0x7f, 0x98, 0x3b, 0x3a, 0x3b, 0xcb, 0xc4, 0x51, 0x83, 0x55, 0x29, 0xd6, 0x30, - 0xe8, 0x51, 0xcc, 0xfe, 0xad, 0xfa, 0x1e, 0xf6, 0xfd, 0x48, 0x1e, 0xde, 0x2c, 0x55, 0xa5, 0x56, - 0x8e, 0x0d, 0xac, 0x9c, 0x28, 0x74, 0x3d, 0x87, 0x8d, 0x42, 0x87, 0xa2, 0x36, 0x1e, 0xf8, 0x3c, - 0x1a, 0xf2, 0xe5, 0x76, 0x1e, 0xf8, 0x07, 0xf7, 0xe5, 0x9d, 0x4f, 0x79, 0x81, 0x0d, 0x31, 0x40, - 0xbd, 0x3c, 0xcc, 0x1e, 0x53, 0x64, 0x56, 0xf8, 0xe8, 0x48, 0x18, 0x5a, 0x84, 0xfe, 0x70, 0x37, - 0xac, 0x46, 0xf5, 0xb0, 0x5d, 0x3a, 0xd2, 0x0a, 0x43, 0xd1, 0xb2, 0x61, 0xf3, 0x2a, 0x58, 0xd6, - 0x45, 0x55, 0x98, 0x14, 0x14, 0xe7, 0xb7, 0x1c, 0x4f, 0x25, 0x49, 0xe4, 0x16, 0x8b, 0x97, 0xf6, - 0xf7, 0x4a, 0x93, 0xa2, 0x65, 0x1d, 0x7c, 0xb0, 0x57, 0xa2, 0x5b, 0x32, 0x03, 0x82, 0xb3, 0xa8, - 0xf1, 0x25, 0x5f, 0xad, 0xfa, 0x8d, 0x66, 0x39, 0xf0, 0x37, 0xdc, 0x3a, 0x69, 0xa7, 0x0c, 0xae, - 0x18, 0x98, 0x62, 0xc9, 0x1b, 0x65, 0x38, 0x41, 0x0d, 0xdd, 0x86, 0x31, 0xa7, 0xd9, 0x9c, 0x0d, - 0x1a, 0x7e, 0x20, 0x1b, 0x18, 0xca, 0xd7, 0x2a, 0xcc, 0x9a, 0xa8, 0x3c, 0x47, 0x62, 0xa2, 0x10, - 0x27, 0x09, 0xd2, 0x81, 0x12, 0x1b, 0xcd, 0x18, 0xa8, 0x91, 0x78, 0xa0, 0xc4, 0xbe, 0xcc, 0x18, - 0xa8, 0x0c, 0x08, 0xce, 0xa2, 0x66, 0xff, 0x00, 0x63, 0xfc, 0x2b, 0xee, 0xa6, 0xc7, 0x9c, 0xe3, - 0x50, 0x03, 0x46, 0x9a, 0xec, 0xd8, 0x17, 0xf9, 0xcb, 0xc4, 0x51, 0xf1, 0x62, 0x97, 0xc2, 0xcb, - 0x3b, 0x2c, 0x03, 0xab, 0x61, 0xc4, 0x5a, 0xd6, 0xc9, 0x61, 0x93, 0xba, 0xfd, 0x8b, 0xd3, 0x8c, - 0x75, 0xac, 0x70, 0x89, 0x64, 0xbf, 0x70, 0x55, 0x14, 0x32, 0x88, 0xe9, 0x7c, 0xd9, 0x7f, 0xbc, - 0xbe, 0x84, 0xbb, 0x23, 0x96, 0x75, 0xd1, 0xa7, 0x60, 0x94, 0x3e, 0xe9, 0x15, 0xfb, 0x16, 0x4e, - 0x1d, 0xcb, 0x8f, 0x81, 0xa5, 0xb0, 0xf4, 0xdc, 0x86, 0x7a, 0x65, 0x9c, 0x20, 0x86, 0xde, 0x62, - 0x76, 0x9d, 0x92, 0x74, 0xa1, 0x1b, 0xd2, 0xba, 0x09, 0xa7, 0x24, 0xab, 0x11, 0x41, 0x2d, 0x98, - 0x4c, 0x67, 0x70, 0x0e, 0xa7, 0xec, 0xfc, 0xb7, 0x51, 0x3a, 0x09, 0x73, 0x9c, 0x84, 0x2e, 0x0d, - 0x0b, 0x71, 0x16, 0x7d, 0x74, 0x3d, 0x99, 0x5f, 0xb7, 0x68, 0x68, 0x0d, 0x52, 0x39, 0x76, 0x47, - 0xda, 0xa6, 0xd6, 0xdd, 0x84, 0x33, 0x5a, 0x8a, 0xd2, 0x2b, 0x81, 0xc3, 0xec, 0x8a, 0x5c, 0x76, - 0x1b, 0x69, 0x4c, 0xed, 0xa3, 0xfb, 0x7b, 0xa5, 0x33, 0x6b, 0xed, 0x10, 0x71, 0x7b, 0x3a, 0xe8, - 0x06, 0x1c, 0xe7, 0x11, 0x5c, 0x16, 0x88, 0x53, 0xab, 0xbb, 0x9e, 0xe2, 0x9a, 0xf9, 0xd9, 0x75, - 0x6a, 0x7f, 0xaf, 0x74, 0x7c, 0x36, 0x0b, 0x01, 0x67, 0xd7, 0x43, 0xaf, 0xc1, 0x60, 0xcd, 0x93, - 0xa7, 0x6c, 0x9f, 0x91, 0x05, 0x76, 0x70, 0x61, 0xb5, 0xa2, 0xbe, 0x3f, 0xfe, 0x83, 0xe3, 0x0a, - 0x68, 0x93, 0xab, 0xad, 0x94, 0xac, 0xb1, 0x3f, 0x15, 0xd8, 0x33, 0x29, 0x8e, 0x37, 0x42, 0x22, - 0x70, 0x7d, 0xad, 0x72, 0xb9, 0x33, 0xa2, 0x25, 0x18, 0x84, 0xd1, 0x9b, 0x80, 0x44, 0xb6, 0xa1, - 0xd9, 0x2a, 0x4b, 0x8e, 0xa7, 0xd9, 0x92, 0x2a, 0x11, 0x42, 0x25, 0x85, 0x81, 0x33, 0x6a, 0xa1, - 0xab, 0xf4, 0x78, 0xd4, 0x4b, 0xc5, 0xf1, 0xab, 0x72, 0x8d, 0x2f, 0x90, 0x66, 0x40, 0x98, 0xf9, - 0xa3, 0x49, 0x11, 0x27, 0xea, 0xa1, 0x1a, 0x9c, 0x76, 0x5a, 0x91, 0xcf, 0x34, 0x82, 0x26, 0xea, - 0x9a, 0xbf, 0x4d, 0x3c, 0xa6, 0x8c, 0x1f, 0x60, 0x01, 0x43, 0x4f, 0xcf, 0xb6, 0xc1, 0xc3, 0x6d, - 0xa9, 0xd0, 0xe7, 0x14, 0x1d, 0x0b, 0x4d, 0x59, 0x67, 0x78, 0x77, 0x73, 0x0d, 0xb6, 0xc4, 0x40, - 0x2f, 0xc1, 0xd0, 0x96, 0x1f, 0x46, 0xab, 0x24, 0xba, 0xe3, 0x07, 0xdb, 0x22, 0xbd, 0x41, 0x9c, - 0x52, 0x26, 0x06, 0x61, 0x1d, 0x0f, 0x3d, 0x05, 0xfd, 0xcc, 0x54, 0x6c, 0x79, 0x81, 0xdd, 0xb5, - 0x03, 0xf1, 0x19, 0x73, 0x95, 0x17, 0x63, 0x09, 0x97, 0xa8, 0xcb, 0xe5, 0x79, 0x76, 0x1c, 0x27, - 0x50, 0x97, 0xcb, 0xf3, 0x58, 0xc2, 0xe9, 0x72, 0x0d, 0xb7, 0x9c, 0x80, 0x94, 0x03, 0xbf, 0x4a, - 0x42, 0x2d, 0x91, 0xd1, 0x23, 0x3c, 0x79, 0x03, 0x5d, 0xae, 0x95, 0x2c, 0x04, 0x9c, 0x5d, 0x0f, - 0x91, 0x74, 0x7a, 0xde, 0xd1, 0x7c, 0x55, 0x69, 0x9a, 0x1d, 0xec, 0x32, 0x43, 0xaf, 0x07, 0xe3, - 0x2a, 0x31, 0x30, 0x4f, 0xd7, 0x10, 0x4e, 0x8d, 0xb1, 0xb5, 0xdd, 0x7d, 0xae, 0x07, 0xa5, 0x7c, - 0x5e, 0x4e, 0x50, 0xc2, 0x29, 0xda, 0x46, 0x44, 0xda, 0xf1, 0x8e, 0x11, 0x69, 0x2f, 0xc2, 0x60, - 0xd8, 0xba, 0x5d, 0xf3, 0x1b, 0x8e, 0xeb, 0x31, 0x8b, 0x1b, 0xed, 0xe1, 0x5e, 0x91, 0x00, 0x1c, - 0xe3, 0xa0, 0x25, 0x18, 0x70, 0xa4, 0x66, 0x19, 0xe5, 0x07, 0xdb, 0x53, 0xfa, 0x64, 0x1e, 0x7f, - 0x4a, 0xea, 0x92, 0x55, 0x5d, 0xf4, 0x2a, 0x8c, 0x88, 0x80, 0x1e, 0x22, 0x97, 0xfe, 0xa4, 0xe9, - 0xbe, 0x5c, 0xd1, 0x81, 0xd8, 0xc4, 0x45, 0xeb, 0x30, 0x14, 0xf9, 0x75, 0xe6, 0x83, 0x4b, 0xb9, - 0xe4, 0x13, 0xf9, 0x31, 0x71, 0xd7, 0x14, 0x9a, 0xae, 0xf3, 0x50, 0x55, 0xb1, 0x4e, 0x07, 0xad, - 0xf1, 0xf5, 0xce, 0xd2, 0x16, 0x91, 0x50, 0x24, 0x63, 0x3f, 0x93, 0x67, 0x2e, 0xc9, 0xd0, 0xcc, - 0xed, 0x20, 0x6a, 0x62, 0x9d, 0x0c, 0xba, 0x02, 0x13, 0xcd, 0xc0, 0xf5, 0xd9, 0x9a, 0x50, 0x9a, - 0xf2, 0x29, 0x33, 0x49, 0x69, 0x39, 0x89, 0x80, 0xd3, 0x75, 0x58, 0x3c, 0x16, 0x51, 0x38, 0x75, - 0x8a, 0x27, 0x5a, 0xe3, 0x72, 0x10, 0x5e, 0x86, 0x15, 0x14, 0xad, 0xb0, 0x93, 0x98, 0x8b, 0xf0, - 0xa6, 0xa6, 0xf3, 0xbd, 0xfc, 0x75, 0x51, 0x1f, 0xe7, 0xfd, 0xd5, 0x5f, 0x1c, 0x53, 0x40, 0x35, - 0x2d, 0xbf, 0x39, 0x7d, 0x41, 0x85, 0x53, 0xa7, 0xdb, 0xd8, 0xeb, 0x26, 0x9e, 0xcb, 0x31, 0x43, - 0x60, 0x14, 0x87, 0x38, 0x41, 0x13, 0xbd, 0x01, 0xe3, 0x22, 0x58, 0x41, 0x3c, 0x4c, 0x67, 0x62, - 0x9f, 0x26, 0x9c, 0x80, 0xe1, 0x14, 0x36, 0x4f, 0x74, 0xe6, 0xdc, 0xae, 0x13, 0x71, 0xf4, 0x5d, - 0x77, 0xbd, 0xed, 0x70, 0xea, 0x2c, 0x3b, 0x1f, 0x44, 0xa2, 0xb3, 0x24, 0x14, 0x67, 0xd4, 0x40, - 0x6b, 0x30, 0xde, 0x0c, 0x08, 0x69, 0xb0, 0x77, 0x92, 0xb8, 0xcf, 0x4a, 0x3c, 0x1c, 0x11, 0xed, - 0x49, 0x39, 0x01, 0x3b, 0xc8, 0x28, 0xc3, 0x29, 0x0a, 0xe8, 0x0e, 0x0c, 0xf8, 0x3b, 0x24, 0xd8, - 0x22, 0x4e, 0x6d, 0xea, 0x5c, 0x1b, 0x4f, 0x3b, 0x71, 0xb9, 0xdd, 0x10, 0xb8, 0x09, 0x43, 0x24, - 0x59, 0xdc, 0xd9, 0x10, 0x49, 0x36, 0x86, 0xfe, 0x0b, 0x0b, 0x4e, 0x49, 0xd5, 0x5e, 0xa5, 0x49, - 0x47, 0x7d, 0xde, 0xf7, 0xc2, 0x28, 0xe0, 0x01, 0x74, 0x1e, 0xcd, 0x0f, 0x2a, 0xb3, 0x96, 0x53, - 0x49, 0x69, 0x11, 0x4e, 0xe5, 0x61, 0x84, 0x38, 0xbf, 0x45, 0xfa, 0xb2, 0x0f, 0x49, 0x24, 0x0f, - 0xa3, 0xd9, 0x70, 0xe9, 0xad, 0x85, 0xd5, 0xa9, 0xc7, 0x78, 0xf4, 0x1f, 0xba, 0x19, 0x2a, 0x49, - 0x20, 0x4e, 0xe3, 0xa3, 0x4b, 0x50, 0xf0, 0xc3, 0xa9, 0xc7, 0xdb, 0xa4, 0xc4, 0xf7, 0x6b, 0x37, - 0x2a, 0xdc, 0x20, 0xf5, 0x46, 0x05, 0x17, 0xfc, 0x50, 0x26, 0x1b, 0xa3, 0xcf, 0xd9, 0x70, 0xea, - 0x09, 0x2e, 0x73, 0x96, 0xc9, 0xc6, 0x58, 0x21, 0x8e, 0xe1, 0x68, 0x0b, 0xc6, 0x42, 0x43, 0x6c, - 0x10, 0x4e, 0x9d, 0x67, 0x23, 0xf5, 0x44, 0xde, 0xa4, 0x19, 0xd8, 0x5a, 0x16, 0x20, 0x93, 0x0a, - 0x4e, 0x92, 0xe5, 0xbb, 0x4b, 0x13, 0x5c, 0x84, 0x53, 0x4f, 0x76, 0xd8, 0x5d, 0x1a, 0xb2, 0xbe, - 0xbb, 0x74, 0x1a, 0x38, 0x41, 0x13, 0xad, 0xeb, 0x6e, 0x8c, 0x17, 0xf2, 0x8d, 0x1b, 0x33, 0x1d, - 0x18, 0x47, 0xf2, 0x9c, 0x17, 0xa7, 0xbf, 0x0f, 0x26, 0x52, 0x5c, 0xd8, 0x61, 0x7c, 0x3a, 0xa6, - 0xb7, 0x61, 0xc4, 0x58, 0xe9, 0x0f, 0xd5, 0xe4, 0xe7, 0xcf, 0x06, 0x61, 0x50, 0x99, 0x62, 0xa0, - 0x8b, 0xa6, 0x95, 0xcf, 0xa9, 0xa4, 0x95, 0xcf, 0x40, 0xd9, 0xaf, 0x19, 0x86, 0x3d, 0x6b, 0x19, - 0xb1, 0x72, 0xf3, 0xce, 0xd5, 0xee, 0x1d, 0xcf, 0x34, 0xf5, 0x52, 0xb1, 0x6b, 0x73, 0xa1, 0x9e, - 0xb6, 0x1a, 0xab, 0x2b, 0x30, 0xe1, 0xf9, 0x8c, 0xf5, 0x27, 0x35, 0xc9, 0xd7, 0x31, 0xf6, 0x6d, - 0x50, 0x8f, 0xe5, 0x96, 0x40, 0xc0, 0xe9, 0x3a, 0xb4, 0x41, 0xce, 0x7f, 0x25, 0x55, 0x64, 0x9c, - 0x3d, 0xc3, 0x02, 0x4a, 0x9f, 0x9c, 0xfc, 0x57, 0x38, 0x35, 0x9e, 0xff, 0xe4, 0xe4, 0x95, 0x92, - 0x3c, 0x5e, 0x28, 0x79, 0x3c, 0xa6, 0x11, 0x6a, 0xfa, 0xb5, 0xe5, 0xb2, 0x78, 0x3d, 0x68, 0x51, - 0xec, 0x6b, 0xcb, 0x65, 0xcc, 0x61, 0x68, 0x16, 0xfa, 0xd8, 0x0f, 0x19, 0x23, 0x27, 0x6f, 0xf7, - 0x2f, 0x97, 0xb5, 0x1c, 0xaa, 0xac, 0x02, 0x16, 0x15, 0x99, 0xc4, 0x9f, 0x3e, 0xb9, 0x98, 0xc4, - 0xbf, 0xff, 0x3e, 0x25, 0xfe, 0x92, 0x00, 0x8e, 0x69, 0xa1, 0xbb, 0x70, 0xdc, 0x78, 0xe6, 0x2a, - 0x4f, 0x3c, 0xc8, 0x37, 0x06, 0x48, 0x20, 0xcf, 0x9d, 0x11, 0x9d, 0x3e, 0xbe, 0x9c, 0x45, 0x09, - 0x67, 0x37, 0x80, 0xea, 0x30, 0x51, 0x4d, 0xb5, 0x3a, 0xd0, 0x7d, 0xab, 0x6a, 0x5d, 0xa4, 0x5b, - 0x4c, 0x13, 0x46, 0xaf, 0xc2, 0xc0, 0xbb, 0x3e, 0x37, 0xdc, 0x13, 0x2f, 0x1e, 0x19, 0x05, 0x66, - 0xe0, 0xad, 0x1b, 0x15, 0x56, 0x7e, 0xb0, 0x57, 0x1a, 0x2a, 0xfb, 0x35, 0xf9, 0x17, 0xab, 0x0a, - 0xe8, 0xc7, 0x2c, 0x98, 0x4e, 0xbf, 0xa3, 0x55, 0xa7, 0x47, 0xba, 0xef, 0xb4, 0x2d, 0x1a, 0x9d, - 0x5e, 0xcc, 0x25, 0x87, 0xdb, 0x34, 0x85, 0x3e, 0x4a, 0xf7, 0x53, 0xe8, 0xde, 0x23, 0x22, 0x01, - 0xfd, 0xa3, 0xf1, 0x7e, 0xa2, 0xa5, 0x07, 0x7b, 0xa5, 0x31, 0x7e, 0xe0, 0xba, 0xf7, 0x54, 0xbc, - 0x7d, 0x5e, 0x01, 0xfd, 0x20, 0x1c, 0x0f, 0xd2, 0x72, 0x6d, 0x22, 0x79, 0xfb, 0xa7, 0xbb, 0x39, - 0xbc, 0x93, 0x13, 0x8e, 0xb3, 0x08, 0xe2, 0xec, 0x76, 0xec, 0xdf, 0xb3, 0x98, 0x3e, 0x43, 0x74, - 0x8b, 0x84, 0xad, 0x7a, 0x74, 0x04, 0xc6, 0x72, 0x8b, 0x86, 0x3d, 0xc1, 0x7d, 0x5b, 0xbb, 0xfd, - 0x2f, 0x16, 0xb3, 0x76, 0x3b, 0x42, 0xbf, 0xbd, 0xb7, 0x60, 0x20, 0x12, 0xad, 0x89, 0xae, 0xe7, - 0x59, 0xe6, 0xc8, 0x4e, 0x31, 0x8b, 0x3f, 0xf5, 0x76, 0x92, 0xa5, 0x58, 0x91, 0xb1, 0xff, 0x47, - 0x3e, 0x03, 0x12, 0x72, 0x04, 0x6a, 0xdb, 0x05, 0x53, 0x6d, 0x5b, 0xea, 0xf0, 0x05, 0x39, 0xea, - 0xdb, 0xff, 0xc1, 0xec, 0x37, 0x93, 0x19, 0xbe, 0xdf, 0xcd, 0x2c, 0xed, 0x2f, 0x5a, 0x00, 0x71, - 0x82, 0x93, 0x2e, 0x12, 0x4e, 0x5f, 0xa6, 0xaf, 0x25, 0x3f, 0xf2, 0xab, 0x7e, 0x5d, 0xa8, 0x8d, - 0x4e, 0xc7, 0x9a, 0x63, 0x5e, 0x7e, 0xa0, 0xfd, 0xc6, 0x0a, 0x1b, 0x95, 0x64, 0xc4, 0xe1, 0x62, - 0x6c, 0xcb, 0x60, 0x44, 0x1b, 0xfe, 0x8a, 0x05, 0xc7, 0xb2, 0x9c, 0x40, 0xe8, 0xdb, 0x9b, 0x4b, - 0x4f, 0x95, 0x09, 0xac, 0x9a, 0xcd, 0x9b, 0xa2, 0x1c, 0x2b, 0x8c, 0xae, 0x33, 0x79, 0x1f, 0x2e, - 0xf9, 0xc6, 0x0d, 0x18, 0x29, 0x07, 0x44, 0xe3, 0x2f, 0x5e, 0x8f, 0xf3, 0x02, 0x0d, 0xce, 0x3d, - 0x7b, 0xe8, 0xc8, 0x4a, 0xf6, 0x57, 0x0b, 0x70, 0x8c, 0x1b, 0x72, 0xcd, 0xee, 0xf8, 0x6e, 0xad, - 0xec, 0xd7, 0x84, 0xeb, 0xee, 0xdb, 0x30, 0xdc, 0xd4, 0x44, 0xde, 0xed, 0x02, 0xc9, 0xeb, 0xa2, - 0xf1, 0x58, 0x48, 0xa7, 0x97, 0x62, 0x83, 0x16, 0xaa, 0xc1, 0x30, 0xd9, 0x71, 0xab, 0xca, 0x1a, - 0xa8, 0x70, 0xe8, 0x4b, 0x5a, 0xb5, 0xb2, 0xa8, 0xd1, 0xc1, 0x06, 0xd5, 0xae, 0xcd, 0xaf, 0x35, - 0x16, 0xad, 0xa7, 0x83, 0x05, 0xd0, 0xcf, 0x5a, 0x70, 0x32, 0x27, 0xec, 0x3c, 0x6d, 0xee, 0x0e, - 0x33, 0x99, 0x13, 0xcb, 0x56, 0x35, 0xc7, 0x0d, 0xe9, 0xb0, 0x80, 0xa2, 0x8f, 0x03, 0x34, 0xe3, - 0x94, 0x9b, 0x1d, 0xe2, 0x73, 0x1b, 0x91, 0x7a, 0xb5, 0xa0, 0xab, 0x2a, 0x33, 0xa7, 0x46, 0xcb, - 0xfe, 0x4a, 0x0f, 0xf4, 0x32, 0xc3, 0x2b, 0x54, 0x86, 0xfe, 0x2d, 0x1e, 0x13, 0xb0, 0xed, 0xbc, - 0x51, 0x5c, 0x19, 0x64, 0x30, 0x9e, 0x37, 0xad, 0x14, 0x4b, 0x32, 0x68, 0x05, 0x26, 0x79, 0x3a, - 0xd1, 0xfa, 0x02, 0xa9, 0x3b, 0xbb, 0x52, 0x9a, 0x5c, 0x60, 0x9f, 0xaa, 0xa4, 0xea, 0xcb, 0x69, - 0x14, 0x9c, 0x55, 0x0f, 0xbd, 0x0e, 0xa3, 0xf4, 0x75, 0xef, 0xb7, 0x22, 0x49, 0x89, 0xe7, 0xef, - 0x54, 0x0f, 0x9e, 0x35, 0x03, 0x8a, 0x13, 0xd8, 0xe8, 0x55, 0x18, 0x69, 0xa6, 0xe4, 0xe6, 0xbd, - 0xb1, 0x80, 0xc9, 0x94, 0x95, 0x9b, 0xb8, 0xcc, 0x0f, 0xa4, 0xc5, 0xbc, 0x5e, 0xd6, 0xb6, 0x02, - 0x12, 0x6e, 0xf9, 0xf5, 0x1a, 0xe3, 0x80, 0x7b, 0x35, 0x3f, 0x90, 0x04, 0x1c, 0xa7, 0x6a, 0x50, - 0x2a, 0x1b, 0x8e, 0x5b, 0x6f, 0x05, 0x24, 0xa6, 0xd2, 0x67, 0x52, 0x59, 0x4a, 0xc0, 0x71, 0xaa, - 0x46, 0x67, 0x85, 0x40, 0xff, 0x83, 0x51, 0x08, 0xd8, 0xbf, 0x5c, 0x00, 0x63, 0x6a, 0xbf, 0x87, - 0xf3, 0x8a, 0xbe, 0x06, 0x3d, 0x9b, 0x41, 0xb3, 0x2a, 0x8c, 0x0c, 0x33, 0xbf, 0xec, 0x0a, 0x2e, - 0xcf, 0xeb, 0x5f, 0x46, 0xff, 0x63, 0x56, 0x8b, 0xee, 0xf1, 0xe3, 0xe5, 0xc0, 0xa7, 0x97, 0x9c, - 0x0c, 0x1b, 0xaa, 0xdc, 0xad, 0xfa, 0xe5, 0x1b, 0xbb, 0x4d, 0x80, 0x6d, 0xe1, 0x33, 0xc2, 0x29, - 0x18, 0xf6, 0x78, 0x15, 0xf1, 0xc2, 0x96, 0x54, 0xd0, 0x25, 0x18, 0x12, 0xa9, 0x1e, 0x99, 0x57, - 0x10, 0xdf, 0x4c, 0xcc, 0x7e, 0x70, 0x21, 0x2e, 0xc6, 0x3a, 0x8e, 0xfd, 0xe3, 0x05, 0x98, 0xcc, - 0x70, 0xeb, 0xe4, 0xd7, 0xc8, 0xa6, 0x1b, 0x46, 0xc1, 0x6e, 0xf2, 0x72, 0xc2, 0xa2, 0x1c, 0x2b, - 0x0c, 0x7a, 0x56, 0xf1, 0x8b, 0x2a, 0x79, 0x39, 0x09, 0xb7, 0x29, 0x01, 0x3d, 0xdc, 0xe5, 0x44, - 0xaf, 0xed, 0x56, 0x48, 0x64, 0x2c, 0x7f, 0x75, 0x6d, 0x33, 0x63, 0x03, 0x06, 0xa1, 0x4f, 0xc0, - 0x4d, 0xa5, 0x41, 0xd7, 0x9e, 0x80, 0x5c, 0x87, 0xce, 0x61, 0xb4, 0x73, 0x11, 0xf1, 0x1c, 0x2f, - 0x12, 0x0f, 0xc5, 0x38, 0xc6, 0x33, 0x2b, 0xc5, 0x02, 0x6a, 0x7f, 0xb9, 0x08, 0xa7, 0x72, 0x1d, - 0xbd, 0x69, 0xd7, 0x1b, 0xbe, 0xe7, 0x46, 0xbe, 0x32, 0xcc, 0xe4, 0x71, 0x9d, 0x49, 0x73, 0x6b, - 0x45, 0x94, 0x63, 0x85, 0x81, 0xce, 0x43, 0x2f, 0x93, 0xb5, 0x27, 0xd3, 0xbc, 0xe1, 0xb9, 0x05, - 0x1e, 0x31, 0x93, 0x83, 0xb5, 0x5b, 0xbd, 0xd8, 0xf6, 0x56, 0x7f, 0x8c, 0x72, 0x30, 0x7e, 0x3d, - 0x79, 0xa1, 0xd0, 0xee, 0xfa, 0x7e, 0x1d, 0x33, 0x20, 0x7a, 0x42, 0x8c, 0x57, 0xc2, 0x12, 0x11, - 0x3b, 0x35, 0x3f, 0xd4, 0x06, 0xed, 0x29, 0xe8, 0xdf, 0x26, 0xbb, 0x81, 0xeb, 0x6d, 0x26, 0x2d, - 0x54, 0xaf, 0xf1, 0x62, 0x2c, 0xe1, 0x66, 0x56, 0xf3, 0xfe, 0x07, 0x91, 0xd5, 0x5c, 0x5f, 0x01, - 0x03, 0x1d, 0xd9, 0x93, 0x9f, 0x28, 0xc2, 0x18, 0x9e, 0x5b, 0xf8, 0x60, 0x22, 0xd6, 0xd3, 0x13, - 0xf1, 0x20, 0x92, 0x7f, 0x1f, 0x6e, 0x36, 0x7e, 0xdb, 0x82, 0x31, 0x96, 0x70, 0x52, 0x44, 0x69, - 0x71, 0x7d, 0xef, 0x08, 0x9e, 0x02, 0x8f, 0x41, 0x6f, 0x40, 0x1b, 0x15, 0x33, 0xa8, 0xf6, 0x38, - 0xeb, 0x09, 0xe6, 0x30, 0x74, 0x1a, 0x7a, 0x58, 0x17, 0xe8, 0xe4, 0x0d, 0xf3, 0x23, 0x78, 0xc1, - 0x89, 0x1c, 0xcc, 0x4a, 0x59, 0xbc, 0x48, 0x4c, 0x9a, 0x75, 0x97, 0x77, 0x3a, 0xb6, 0x84, 0x78, - 0x7f, 0x84, 0x80, 0xc9, 0xec, 0xda, 0x7b, 0x8b, 0x17, 0x99, 0x4d, 0xb2, 0xfd, 0x33, 0xfb, 0x1f, - 0x0a, 0x70, 0x36, 0xb3, 0x5e, 0xd7, 0xf1, 0x22, 0xdb, 0xd7, 0x7e, 0x98, 0xe9, 0xe9, 0x8a, 0x47, - 0x68, 0xff, 0xdf, 0xd3, 0x2d, 0xf7, 0xdf, 0xdb, 0x45, 0x18, 0xc7, 0xcc, 0x21, 0x7b, 0x9f, 0x84, - 0x71, 0xcc, 0xec, 0x5b, 0x8e, 0x98, 0xe0, 0x5f, 0x0b, 0x39, 0xdf, 0xc2, 0x04, 0x06, 0x17, 0xe8, - 0x39, 0xc3, 0x80, 0xa1, 0x7c, 0x84, 0xf3, 0x33, 0x86, 0x97, 0x61, 0x05, 0x45, 0xb3, 0x30, 0xd6, - 0x70, 0x3d, 0x7a, 0xf8, 0xec, 0x9a, 0xac, 0xb8, 0x52, 0x91, 0xac, 0x98, 0x60, 0x9c, 0xc4, 0x47, - 0xae, 0x16, 0xe2, 0x91, 0x7f, 0xdd, 0xab, 0x87, 0xda, 0x75, 0x33, 0xa6, 0x95, 0x88, 0x1a, 0xc5, - 0x8c, 0x70, 0x8f, 0x2b, 0x9a, 0x9c, 0xa8, 0xd8, 0xbd, 0x9c, 0x68, 0x38, 0x5b, 0x46, 0x34, 0xfd, - 0x2a, 0x8c, 0xdc, 0xb7, 0x6e, 0xc4, 0xfe, 0x56, 0x11, 0x1e, 0x69, 0xb3, 0xed, 0xf9, 0x59, 0x6f, - 0xcc, 0x81, 0x76, 0xd6, 0xa7, 0xe6, 0xa1, 0x0c, 0xc7, 0x36, 0x5a, 0xf5, 0xfa, 0x2e, 0x73, 0x74, - 0x23, 0x35, 0x89, 0x21, 0x78, 0x4a, 0x29, 0x1c, 0x39, 0xb6, 0x94, 0x81, 0x83, 0x33, 0x6b, 0xd2, - 0x27, 0x16, 0xbd, 0x49, 0x76, 0x15, 0xa9, 0xc4, 0x13, 0x0b, 0xeb, 0x40, 0x6c, 0xe2, 0xa2, 0x2b, - 0x30, 0xe1, 0xec, 0x38, 0x2e, 0x4f, 0xef, 0x21, 0x09, 0xf0, 0x37, 0x96, 0x92, 0x45, 0xcf, 0x26, - 0x11, 0x70, 0xba, 0x0e, 0x7a, 0x13, 0x90, 0x7f, 0x9b, 0x39, 0xcf, 0xd4, 0xae, 0x10, 0x4f, 0x28, - 0xf3, 0xd9, 0xdc, 0x15, 0xe3, 0x23, 0xe1, 0x46, 0x0a, 0x03, 0x67, 0xd4, 0x4a, 0x04, 0x1b, 0xec, - 0xcb, 0x0f, 0x36, 0xd8, 0xfe, 0x5c, 0xec, 0x98, 0x19, 0xf1, 0x1d, 0x18, 0x39, 0xac, 0xb5, 0xf7, - 0x53, 0xd0, 0x1f, 0x88, 0x9c, 0xf3, 0x09, 0xaf, 0x72, 0x99, 0x91, 0x5b, 0xc2, 0xed, 0xff, 0xc7, - 0x02, 0x25, 0x4b, 0x36, 0xe3, 0x8a, 0xbf, 0xca, 0x4c, 0xd7, 0xb9, 0x14, 0x5c, 0x0b, 0x25, 0x76, - 0x5c, 0x33, 0x5d, 0x8f, 0x81, 0xd8, 0xc4, 0xe5, 0xcb, 0x2d, 0x8c, 0x23, 0x58, 0x18, 0x0f, 0x08, - 0xa1, 0x35, 0x54, 0x18, 0xe8, 0x13, 0xd0, 0x5f, 0x73, 0x77, 0xdc, 0x50, 0xc8, 0xd1, 0x0e, 0xad, - 0xb7, 0x8b, 0xbf, 0x6f, 0x81, 0x93, 0xc1, 0x92, 0x9e, 0xfd, 0x53, 0x16, 0x28, 0x75, 0xe7, 0x55, - 0xe2, 0xd4, 0xa3, 0x2d, 0xf4, 0x06, 0x80, 0xa4, 0xa0, 0x64, 0x6f, 0xd2, 0x08, 0x0b, 0xb0, 0x82, - 0x1c, 0x18, 0xff, 0xb0, 0x56, 0x07, 0xbd, 0x0e, 0x7d, 0x5b, 0x8c, 0x96, 0xf8, 0xb6, 0xf3, 0x4a, - 0xd5, 0xc5, 0x4a, 0x0f, 0xf6, 0x4a, 0xc7, 0xcc, 0x36, 0xe5, 0x2d, 0xc6, 0x6b, 0xd9, 0x3f, 0x51, - 0x88, 0xe7, 0xf4, 0xad, 0x96, 0x1f, 0x39, 0x47, 0xc0, 0x89, 0x5c, 0x31, 0x38, 0x91, 0x27, 0xda, - 0xe9, 0x73, 0x59, 0x97, 0x72, 0x39, 0x90, 0x1b, 0x09, 0x0e, 0xe4, 0xc9, 0xce, 0xa4, 0xda, 0x73, - 0x1e, 0xff, 0x93, 0x05, 0x13, 0x06, 0xfe, 0x11, 0x5c, 0x80, 0x4b, 0xe6, 0x05, 0xf8, 0x68, 0xc7, - 0x6f, 0xc8, 0xb9, 0xf8, 0x7e, 0xb4, 0x98, 0xe8, 0x3b, 0xbb, 0xf0, 0xde, 0x85, 0x9e, 0x2d, 0x27, - 0xa8, 0x89, 0x77, 0xfd, 0xc5, 0xae, 0xc6, 0x7a, 0xe6, 0xaa, 0x13, 0x08, 0x03, 0x8e, 0x67, 0xe5, - 0xa8, 0xd3, 0xa2, 0x8e, 0xc6, 0x1b, 0xac, 0x29, 0x74, 0x19, 0xfa, 0xc2, 0xaa, 0xdf, 0x54, 0x7e, - 0x80, 0x2c, 0x5d, 0x78, 0x85, 0x95, 0x1c, 0xec, 0x95, 0x90, 0xd9, 0x1c, 0x2d, 0xc6, 0x02, 0x1f, - 0xbd, 0x0d, 0x23, 0xec, 0x97, 0xb2, 0xa6, 0x2c, 0xe6, 0x4b, 0x60, 0x2a, 0x3a, 0x22, 0x37, 0x35, - 0x36, 0x8a, 0xb0, 0x49, 0x6a, 0x7a, 0x13, 0x06, 0xd5, 0x67, 0x3d, 0x54, 0x6d, 0xfd, 0xff, 0x59, - 0x84, 0xc9, 0x8c, 0x35, 0x87, 0x42, 0x63, 0x26, 0x2e, 0x75, 0xb9, 0x54, 0xdf, 0xe3, 0x5c, 0x84, - 0xec, 0x01, 0x58, 0x13, 0x6b, 0xab, 0xeb, 0x46, 0xd7, 0x43, 0x92, 0x6c, 0x94, 0x16, 0x75, 0x6e, - 0x94, 0x36, 0x76, 0x64, 0x43, 0x4d, 0x1b, 0x52, 0x3d, 0x7d, 0xa8, 0x73, 0xfa, 0x87, 0x3d, 0x70, - 0x2c, 0xcb, 0xc4, 0x04, 0x7d, 0x0e, 0xfa, 0x98, 0xa3, 0x9a, 0x14, 0x9c, 0xbd, 0xd8, 0xad, 0x71, - 0xca, 0x0c, 0xf3, 0x75, 0x13, 0xa1, 0x69, 0x67, 0xe4, 0x71, 0xc4, 0x0b, 0x3b, 0x0e, 0xb3, 0x68, - 0x93, 0x85, 0x8c, 0x12, 0xb7, 0xa7, 0x3c, 0x3e, 0x3e, 0xd2, 0x75, 0x07, 0xc4, 0xfd, 0x1b, 0x26, - 0x2c, 0xb5, 0x64, 0x71, 0x67, 0x4b, 0x2d, 0xd9, 0x32, 0x5a, 0x86, 0xbe, 0x2a, 0x37, 0x01, 0x2a, - 0x76, 0x3e, 0xc2, 0xb8, 0xfd, 0x8f, 0x3a, 0x80, 0x85, 0xdd, 0x8f, 0x20, 0x30, 0xed, 0xc2, 0x90, - 0x36, 0x30, 0x0f, 0x75, 0xf1, 0x6c, 0xd3, 0x8b, 0x4f, 0x1b, 0x82, 0x87, 0xba, 0x80, 0x7e, 0x46, - 0xbb, 0xfb, 0xc5, 0x79, 0xf0, 0x61, 0x83, 0x77, 0x3a, 0x9d, 0x70, 0x1f, 0x4c, 0xec, 0x2b, 0xc6, - 0x4b, 0x55, 0xcc, 0x98, 0xee, 0xb9, 0xa9, 0xa1, 0xcc, 0x0b, 0xbf, 0x7d, 0x1c, 0x77, 0xfb, 0x67, - 0x2d, 0x48, 0x38, 0x78, 0x29, 0x71, 0xa7, 0x95, 0x2b, 0xee, 0x3c, 0x07, 0x3d, 0x81, 0x5f, 0x27, - 0xc9, 0xd4, 0xfb, 0xd8, 0xaf, 0x13, 0xcc, 0x20, 0x14, 0x23, 0x8a, 0x85, 0x58, 0xc3, 0xfa, 0x03, - 0x5d, 0x3c, 0xbd, 0x1f, 0x83, 0xde, 0x3a, 0xd9, 0x21, 0xf5, 0x64, 0x86, 0xd4, 0xeb, 0xb4, 0x10, - 0x73, 0x98, 0xfd, 0xdb, 0x3d, 0x70, 0xa6, 0x6d, 0x64, 0x39, 0xca, 0x60, 0x6e, 0x3a, 0x11, 0xb9, - 0xe3, 0xec, 0x26, 0x33, 0x03, 0x5e, 0xe1, 0xc5, 0x58, 0xc2, 0x99, 0xb3, 0x35, 0xcf, 0x94, 0x93, - 0x10, 0x0e, 0x8b, 0x04, 0x39, 0x02, 0x6a, 0x0a, 0x1b, 0x8b, 0x0f, 0x42, 0xd8, 0xf8, 0x3c, 0x40, - 0x18, 0xd6, 0xb9, 0x1d, 0x67, 0x4d, 0x78, 0x71, 0xc7, 0x19, 0x95, 0x2a, 0xd7, 0x05, 0x04, 0x6b, - 0x58, 0x68, 0x01, 0xc6, 0x9b, 0x81, 0x1f, 0x71, 0x59, 0xfb, 0x02, 0x37, 0x75, 0xee, 0x35, 0x83, - 0x7a, 0x95, 0x13, 0x70, 0x9c, 0xaa, 0x81, 0x5e, 0x82, 0x21, 0x11, 0xe8, 0xab, 0xec, 0xfb, 0x75, - 0x21, 0xde, 0x53, 0xd6, 0xbf, 0x95, 0x18, 0x84, 0x75, 0x3c, 0xad, 0x1a, 0x13, 0xe0, 0xf7, 0x67, - 0x56, 0xe3, 0x42, 0x7c, 0x0d, 0x2f, 0x91, 0x14, 0x60, 0xa0, 0xab, 0xa4, 0x00, 0xb1, 0xc0, 0x73, - 0xb0, 0x6b, 0x7d, 0x32, 0x74, 0x14, 0x11, 0x7e, 0xad, 0x07, 0x26, 0xc5, 0xc2, 0x79, 0xd8, 0xcb, - 0x65, 0x3d, 0xbd, 0x5c, 0x1e, 0x84, 0x48, 0xf4, 0x83, 0x35, 0x73, 0xd4, 0x6b, 0xe6, 0x27, 0x2d, - 0x30, 0x79, 0x48, 0xf4, 0x9f, 0xe5, 0xa6, 0x56, 0x7d, 0x29, 0x97, 0x27, 0x8d, 0x23, 0x86, 0xbf, - 0xb7, 0x24, 0xab, 0xf6, 0xff, 0x65, 0xc1, 0xa3, 0x1d, 0x29, 0xa2, 0x45, 0x18, 0x64, 0x8c, 0xae, - 0xf6, 0x2e, 0x7e, 0x52, 0xb9, 0x42, 0x48, 0x40, 0x0e, 0xdf, 0x1d, 0xd7, 0x44, 0x8b, 0xa9, 0x1c, - 0xb6, 0x4f, 0x65, 0xe4, 0xb0, 0x3d, 0x6e, 0x0c, 0xcf, 0x7d, 0x26, 0xb1, 0xfd, 0x12, 0xbd, 0x71, - 0x4c, 0x7f, 0xca, 0x8f, 0x18, 0xe2, 0x5c, 0x3b, 0x21, 0xce, 0x45, 0x26, 0xb6, 0x76, 0x87, 0xbc, - 0x01, 0xe3, 0x2c, 0x02, 0x28, 0x73, 0xcc, 0x11, 0x8e, 0x98, 0x85, 0xd8, 0xf8, 0xfe, 0x7a, 0x02, - 0x86, 0x53, 0xd8, 0xf6, 0xdf, 0x15, 0xa1, 0x8f, 0x6f, 0xbf, 0x23, 0x78, 0xf8, 0x3e, 0x03, 0x83, - 0x6e, 0xa3, 0xd1, 0xe2, 0x69, 0x49, 0x7b, 0x63, 0x53, 0xee, 0x65, 0x59, 0x88, 0x63, 0x38, 0x5a, - 0x12, 0x9a, 0x84, 0x36, 0x41, 0xc6, 0x79, 0xc7, 0x67, 0x16, 0x9c, 0xc8, 0xe1, 0x5c, 0x9c, 0xba, - 0x67, 0x63, 0x9d, 0x03, 0xfa, 0x34, 0x40, 0x18, 0x05, 0xae, 0xb7, 0x49, 0xcb, 0x44, 0x26, 0x8a, - 0xa7, 0xdb, 0x50, 0xab, 0x28, 0x64, 0x4e, 0x33, 0x3e, 0x73, 0x14, 0x00, 0x6b, 0x14, 0xd1, 0x8c, - 0x71, 0xd3, 0x4f, 0x27, 0xe6, 0x0e, 0x38, 0xd5, 0x78, 0xce, 0xa6, 0x5f, 0x86, 0x41, 0x45, 0xbc, - 0x93, 0x5c, 0x71, 0x58, 0x67, 0xd8, 0x3e, 0x06, 0x63, 0x89, 0xbe, 0x1d, 0x4a, 0x2c, 0xf9, 0x3b, - 0x16, 0x8c, 0xf1, 0xce, 0x2c, 0x7a, 0x3b, 0xe2, 0x36, 0xb8, 0x07, 0xc7, 0xea, 0x19, 0xa7, 0xb2, - 0x98, 0xfe, 0xee, 0x4f, 0x71, 0x25, 0x86, 0xcc, 0x82, 0xe2, 0xcc, 0x36, 0xd0, 0x05, 0xba, 0xe3, - 0xe8, 0xa9, 0xeb, 0xd4, 0x45, 0x34, 0x91, 0x61, 0xbe, 0xdb, 0x78, 0x19, 0x56, 0x50, 0xfb, 0xaf, - 0x2c, 0x98, 0xe0, 0x3d, 0xbf, 0x46, 0x76, 0xd5, 0xd9, 0xf4, 0x9d, 0xec, 0xbb, 0x48, 0x88, 0x5d, - 0xc8, 0x49, 0x88, 0xad, 0x7f, 0x5a, 0xb1, 0xed, 0xa7, 0x7d, 0xd5, 0x02, 0xb1, 0x42, 0x8e, 0x40, - 0xd2, 0xf2, 0x7d, 0xa6, 0xa4, 0x65, 0x3a, 0x7f, 0x13, 0xe4, 0x88, 0x58, 0xfe, 0xc5, 0x82, 0x71, - 0x8e, 0x10, 0x5b, 0x41, 0x7c, 0x47, 0xe7, 0x61, 0xce, 0xfc, 0xa2, 0x4c, 0xb3, 0xd6, 0x6b, 0x64, - 0x77, 0xcd, 0x2f, 0x3b, 0xd1, 0x56, 0xf6, 0x47, 0x19, 0x93, 0xd5, 0xd3, 0x76, 0xb2, 0x6a, 0x72, - 0x03, 0x19, 0x89, 0x17, 0x3b, 0x08, 0x80, 0x0f, 0x9b, 0x78, 0xd1, 0xfe, 0x7b, 0x0b, 0x10, 0x6f, - 0xc6, 0x60, 0xdc, 0x28, 0x3b, 0xc4, 0x4a, 0xb5, 0x8b, 0x2e, 0x3e, 0x9a, 0x14, 0x04, 0x6b, 0x58, - 0x0f, 0x64, 0x78, 0x12, 0xa6, 0x2c, 0xc5, 0xce, 0xa6, 0x2c, 0x87, 0x18, 0xd1, 0xaf, 0xf6, 0x43, - 0xd2, 0x15, 0x13, 0xdd, 0x84, 0xe1, 0xaa, 0xd3, 0x74, 0x6e, 0xbb, 0x75, 0x37, 0x72, 0x49, 0xd8, - 0xce, 0xce, 0x6d, 0x5e, 0xc3, 0x13, 0xc6, 0x07, 0x5a, 0x09, 0x36, 0xe8, 0xa0, 0x19, 0x80, 0x66, - 0xe0, 0xee, 0xb8, 0x75, 0xb2, 0xc9, 0x04, 0x42, 0x2c, 0x7e, 0x11, 0x37, 0xba, 0x93, 0xa5, 0x58, - 0xc3, 0xc8, 0x08, 0x1b, 0x52, 0x7c, 0xc8, 0x61, 0x43, 0xe0, 0xc8, 0xc2, 0x86, 0xf4, 0x1c, 0x2a, - 0x6c, 0xc8, 0xc0, 0xa1, 0xc3, 0x86, 0xf4, 0x76, 0x15, 0x36, 0x04, 0xc3, 0x09, 0xc9, 0x7b, 0xd2, - 0xff, 0x4b, 0x6e, 0x9d, 0x88, 0x07, 0x07, 0x0f, 0xba, 0x34, 0xbd, 0xbf, 0x57, 0x3a, 0x81, 0x33, - 0x31, 0x70, 0x4e, 0x4d, 0xf4, 0x71, 0x98, 0x72, 0xea, 0x75, 0xff, 0x8e, 0x9a, 0xd4, 0xc5, 0xb0, - 0xea, 0xd4, 0xb9, 0x72, 0xa9, 0x9f, 0x51, 0x3d, 0xbd, 0xbf, 0x57, 0x9a, 0x9a, 0xcd, 0xc1, 0xc1, - 0xb9, 0xb5, 0xd1, 0x6b, 0x30, 0xd8, 0x0c, 0xfc, 0xea, 0x8a, 0xe6, 0x2f, 0x7e, 0x96, 0x0e, 0x60, - 0x59, 0x16, 0x1e, 0xec, 0x95, 0x46, 0xd4, 0x1f, 0x76, 0xe1, 0xc7, 0x15, 0x32, 0x22, 0x72, 0x0c, - 0x3d, 0xec, 0x88, 0x1c, 0xc3, 0x0f, 0x38, 0x22, 0x87, 0xbd, 0x0d, 0x93, 0x15, 0x12, 0xb8, 0x4e, - 0xdd, 0xbd, 0x47, 0x79, 0x72, 0x79, 0x06, 0xae, 0xc1, 0x60, 0x90, 0x38, 0xf5, 0xbb, 0x0a, 0x2e, - 0xae, 0xc9, 0x65, 0xe4, 0x29, 0x1f, 0x13, 0xb2, 0xff, 0xbd, 0x05, 0xfd, 0xc2, 0xbd, 0xf3, 0x08, - 0x38, 0xd3, 0x59, 0x43, 0x25, 0x53, 0xca, 0x9e, 0x14, 0xd6, 0x99, 0x5c, 0x65, 0xcc, 0x72, 0x42, - 0x19, 0xf3, 0x68, 0x3b, 0x22, 0xed, 0xd5, 0x30, 0xff, 0x75, 0x91, 0xbe, 0x10, 0x8c, 0x40, 0x03, - 0x0f, 0x7f, 0x08, 0x56, 0xa1, 0x3f, 0x14, 0x8e, 0xee, 0x85, 0x7c, 0x5f, 0x9e, 0xe4, 0x24, 0xc6, - 0x36, 0x90, 0xc2, 0xb5, 0x5d, 0x12, 0xc9, 0xf4, 0xa0, 0x2f, 0x3e, 0x44, 0x0f, 0xfa, 0x4e, 0xa1, - 0x18, 0x7a, 0x1e, 0x44, 0x28, 0x06, 0xfb, 0x1b, 0xec, 0x76, 0xd6, 0xcb, 0x8f, 0x80, 0x71, 0xbb, - 0x62, 0xde, 0xe3, 0x76, 0x9b, 0x95, 0x25, 0x3a, 0x95, 0xc3, 0xc0, 0xfd, 0x96, 0x05, 0x67, 0x32, - 0xbe, 0x4a, 0xe3, 0xe6, 0x9e, 0x85, 0x01, 0xa7, 0x55, 0x73, 0xd5, 0x5e, 0xd6, 0xb4, 0xc5, 0xb3, - 0xa2, 0x1c, 0x2b, 0x0c, 0x34, 0x0f, 0x13, 0xe4, 0x6e, 0xd3, 0xe5, 0x6a, 0x78, 0xdd, 0x74, 0xbc, - 0xc8, 0x7d, 0x82, 0x17, 0x93, 0x40, 0x9c, 0xc6, 0x57, 0xe1, 0xdc, 0x8a, 0xb9, 0xe1, 0xdc, 0x7e, - 0xdd, 0x82, 0x21, 0xe5, 0xea, 0xfd, 0xd0, 0x47, 0xfb, 0x0d, 0x73, 0xb4, 0x1f, 0x69, 0x33, 0xda, - 0x39, 0xc3, 0xfc, 0x97, 0x05, 0xd5, 0xdf, 0xb2, 0x1f, 0x44, 0x5d, 0x70, 0x89, 0xf7, 0xef, 0xf6, - 0x72, 0x09, 0x86, 0x9c, 0x66, 0x53, 0x02, 0xa4, 0xfd, 0x22, 0x4b, 0x15, 0x11, 0x17, 0x63, 0x1d, - 0x47, 0x79, 0xe1, 0x14, 0x73, 0xbd, 0x70, 0x6a, 0x00, 0x91, 0x13, 0x6c, 0x92, 0x88, 0x96, 0x09, - 0x73, 0xeb, 0xfc, 0xf3, 0xa6, 0x15, 0xb9, 0xf5, 0x19, 0xd7, 0x8b, 0xc2, 0x28, 0x98, 0x59, 0xf6, - 0xa2, 0x1b, 0x01, 0x7f, 0xa6, 0x6a, 0x41, 0x13, 0x15, 0x2d, 0xac, 0xd1, 0x95, 0x61, 0x4d, 0x58, - 0x1b, 0xbd, 0xa6, 0x21, 0xcc, 0xaa, 0x28, 0xc7, 0x0a, 0xc3, 0x7e, 0x99, 0xdd, 0x3e, 0x6c, 0x4c, - 0x0f, 0x17, 0x0c, 0xf0, 0x1f, 0x86, 0xd5, 0x6c, 0x30, 0x95, 0xf0, 0x82, 0x1e, 0x72, 0xb0, 0xfd, - 0x61, 0x4f, 0x1b, 0xd6, 0xfd, 0x59, 0xe3, 0xb8, 0x84, 0xe8, 0x93, 0x29, 0xe3, 0xa6, 0xe7, 0x3a, - 0xdc, 0x1a, 0x87, 0x30, 0x67, 0x62, 0x79, 0xe3, 0x58, 0x56, 0xad, 0xe5, 0xb2, 0xd8, 0x17, 0x5a, - 0xde, 0x38, 0x01, 0xc0, 0x31, 0x0e, 0x65, 0xd8, 0xd4, 0x9f, 0x70, 0x0a, 0xc5, 0xe1, 0xc5, 0x15, - 0x76, 0x88, 0x35, 0x0c, 0x74, 0x51, 0x08, 0x2d, 0xb8, 0xee, 0xe1, 0x91, 0x84, 0xd0, 0x42, 0x0e, - 0x97, 0x26, 0x69, 0xba, 0x04, 0x43, 0xe4, 0x6e, 0x44, 0x02, 0xcf, 0xa9, 0xd3, 0x16, 0x7a, 0xe3, - 0x88, 0xb8, 0x8b, 0x71, 0x31, 0xd6, 0x71, 0xd0, 0x1a, 0x8c, 0x85, 0x5c, 0x96, 0xa7, 0x92, 0x5a, - 0x70, 0x99, 0xe8, 0xd3, 0xca, 0xc9, 0xde, 0x04, 0x1f, 0xb0, 0x22, 0x7e, 0x3a, 0xc9, 0xd0, 0x23, - 0x49, 0x12, 0xe8, 0x75, 0x18, 0xad, 0xfb, 0x4e, 0x6d, 0xce, 0xa9, 0x3b, 0x5e, 0x95, 0x8d, 0xcf, - 0x80, 0x11, 0x7f, 0x72, 0xf4, 0xba, 0x01, 0xc5, 0x09, 0x6c, 0xca, 0x20, 0xea, 0x25, 0x22, 0x11, - 0x8b, 0xe3, 0x6d, 0x92, 0x70, 0x6a, 0x90, 0x7d, 0x15, 0x63, 0x10, 0xaf, 0xe7, 0xe0, 0xe0, 0xdc, - 0xda, 0xe8, 0x32, 0x0c, 0xcb, 0xcf, 0xd7, 0x22, 0xf5, 0xc4, 0x0e, 0x4d, 0x1a, 0x0c, 0x1b, 0x98, - 0x28, 0x84, 0xe3, 0xf2, 0xff, 0x5a, 0xe0, 0x6c, 0x6c, 0xb8, 0x55, 0x11, 0xbe, 0x82, 0x3b, 0x7f, - 0x7f, 0x4c, 0x7a, 0x9a, 0x2e, 0x66, 0x21, 0x1d, 0xec, 0x95, 0x4e, 0x8b, 0x51, 0xcb, 0x84, 0xe3, - 0x6c, 0xda, 0x68, 0x05, 0x26, 0xb9, 0x0d, 0xcc, 0xfc, 0x16, 0xa9, 0x6e, 0xcb, 0x0d, 0xc7, 0xb8, - 0x46, 0xcd, 0xf1, 0xe7, 0x6a, 0x1a, 0x05, 0x67, 0xd5, 0x43, 0xef, 0xc0, 0x54, 0xb3, 0x75, 0xbb, - 0xee, 0x86, 0x5b, 0xab, 0x7e, 0xc4, 0x4c, 0xc8, 0x66, 0x6b, 0xb5, 0x80, 0x84, 0xdc, 0x37, 0x98, - 0x5d, 0xbd, 0x32, 0xba, 0x52, 0x39, 0x07, 0x0f, 0xe7, 0x52, 0x40, 0xf7, 0xe0, 0x78, 0x62, 0x21, - 0x88, 0x30, 0x29, 0xa3, 0xf9, 0x29, 0xad, 0x2a, 0x59, 0x15, 0x44, 0xc4, 0xa1, 0x2c, 0x10, 0xce, - 0x6e, 0x02, 0xbd, 0x02, 0xe0, 0x36, 0x97, 0x9c, 0x86, 0x5b, 0xa7, 0xcf, 0xd1, 0x49, 0xb6, 0x46, - 0xe8, 0xd3, 0x04, 0x96, 0xcb, 0xb2, 0x94, 0x9e, 0xcd, 0xe2, 0xdf, 0x2e, 0xd6, 0xb0, 0xd1, 0x75, - 0x18, 0x15, 0xff, 0x76, 0xc5, 0x94, 0x4e, 0xa8, 0xec, 0xa7, 0xa3, 0xb2, 0x86, 0x9a, 0xc7, 0x44, - 0x09, 0x4e, 0xd4, 0x45, 0x9b, 0x70, 0x46, 0xa6, 0x5e, 0xd5, 0xd7, 0xa7, 0x9c, 0x83, 0x90, 0xe5, - 0x91, 0x1a, 0xe0, 0x3e, 0x45, 0xb3, 0xed, 0x10, 0x71, 0x7b, 0x3a, 0xf4, 0x5e, 0xd7, 0x97, 0x39, - 0xf7, 0x18, 0x3f, 0x1e, 0x47, 0xf1, 0xbc, 0x9e, 0x04, 0xe2, 0x34, 0x3e, 0xf2, 0xe1, 0xb8, 0xeb, - 0x65, 0xad, 0xea, 0x13, 0x8c, 0xd0, 0x47, 0xb9, 0xb3, 0x7c, 0xfb, 0x15, 0x9d, 0x09, 0xc7, 0xd9, - 0x74, 0xd1, 0x32, 0x4c, 0x46, 0xbc, 0x60, 0xc1, 0x0d, 0x79, 0x9a, 0x1a, 0xfa, 0xec, 0x3b, 0xc9, - 0x9a, 0x3b, 0x49, 0x57, 0xf3, 0x5a, 0x1a, 0x8c, 0xb3, 0xea, 0xbc, 0x37, 0x03, 0xd0, 0x6f, 0x5a, - 0xb4, 0xb6, 0xc6, 0xe8, 0xa3, 0xcf, 0xc0, 0xb0, 0x3e, 0x3e, 0x82, 0x69, 0x39, 0x9f, 0xcd, 0x07, - 0x6b, 0xc7, 0x0b, 0x7f, 0x26, 0xa8, 0x23, 0x44, 0x87, 0x61, 0x83, 0x22, 0xaa, 0x66, 0x04, 0xb9, - 0xb8, 0xd8, 0x1d, 0x53, 0xd4, 0xbd, 0xfd, 0x23, 0x81, 0xec, 0x9d, 0x83, 0xae, 0xc3, 0x40, 0xb5, - 0xee, 0x12, 0x2f, 0x5a, 0x2e, 0xb7, 0x0b, 0xae, 0x3a, 0x2f, 0x70, 0xc4, 0x56, 0x14, 0xd9, 0xa5, - 0x78, 0x19, 0x56, 0x14, 0xec, 0xcb, 0x30, 0x54, 0xa9, 0x13, 0xd2, 0xe4, 0x7e, 0x5c, 0xe8, 0x29, - 0xf6, 0x30, 0x61, 0xac, 0xa5, 0xc5, 0x58, 0x4b, 0xfd, 0xcd, 0xc1, 0x98, 0x4a, 0x09, 0xb7, 0xff, - 0xb8, 0x00, 0xa5, 0x0e, 0x49, 0xce, 0x12, 0xfa, 0x36, 0xab, 0x2b, 0x7d, 0xdb, 0x2c, 0x8c, 0xc5, - 0xff, 0x74, 0x51, 0x9e, 0x32, 0x86, 0xbe, 0x69, 0x82, 0x71, 0x12, 0xbf, 0x6b, 0xbf, 0x16, 0x5d, - 0x65, 0xd7, 0xd3, 0xd1, 0x33, 0xcb, 0x50, 0xd5, 0xf7, 0x76, 0xff, 0xf6, 0xce, 0x55, 0xbb, 0xda, - 0xdf, 0x28, 0xc0, 0x71, 0x35, 0x84, 0xdf, 0xbb, 0x03, 0xb7, 0x9e, 0x1e, 0xb8, 0x07, 0xa0, 0xb4, - 0xb6, 0x6f, 0x40, 0x1f, 0x8f, 0xf8, 0xda, 0x05, 0xcf, 0xff, 0x98, 0x19, 0x7c, 0x5f, 0xb1, 0x99, - 0x46, 0x00, 0xfe, 0x1f, 0xb3, 0x60, 0x2c, 0xe1, 0x20, 0x89, 0xb0, 0xe6, 0x45, 0x7f, 0x3f, 0x7c, - 0x79, 0x16, 0xc7, 0x7f, 0x0e, 0x7a, 0xb6, 0x7c, 0x65, 0xa4, 0xac, 0x30, 0xae, 0xfa, 0x61, 0x84, - 0x19, 0xc4, 0xfe, 0x6b, 0x0b, 0x7a, 0xd7, 0x1c, 0xd7, 0x8b, 0xa4, 0xf6, 0xc3, 0xca, 0xd1, 0x7e, - 0x74, 0xf3, 0x5d, 0xe8, 0x25, 0xe8, 0x23, 0x1b, 0x1b, 0xa4, 0x1a, 0x89, 0x59, 0x95, 0xd1, 0x34, - 0xfa, 0x16, 0x59, 0x29, 0x65, 0x42, 0x59, 0x63, 0xfc, 0x2f, 0x16, 0xc8, 0xe8, 0x16, 0x0c, 0x46, - 0x6e, 0x83, 0xcc, 0xd6, 0x6a, 0xc2, 0x26, 0xe0, 0x3e, 0x42, 0xc0, 0xac, 0x49, 0x02, 0x38, 0xa6, - 0x65, 0x7f, 0xb9, 0x00, 0x10, 0x47, 0x98, 0xeb, 0xf4, 0x89, 0x73, 0x29, 0x6d, 0xf1, 0xf9, 0x0c, - 0x6d, 0x31, 0x8a, 0x09, 0x66, 0xa8, 0x8a, 0xd5, 0x30, 0x15, 0xbb, 0x1a, 0xa6, 0x9e, 0xc3, 0x0c, - 0xd3, 0x3c, 0x4c, 0xc4, 0x11, 0xf2, 0xcc, 0x00, 0xa1, 0xec, 0xfe, 0x5e, 0x4b, 0x02, 0x71, 0x1a, - 0xdf, 0x26, 0x70, 0x4e, 0x05, 0x0a, 0x13, 0x77, 0x21, 0x73, 0x25, 0xd0, 0xb5, 0xef, 0x1d, 0xc6, - 0x29, 0x56, 0x87, 0x17, 0x72, 0xd5, 0xe1, 0xbf, 0x60, 0xc1, 0xb1, 0x64, 0x3b, 0xcc, 0xef, 0xfe, - 0x8b, 0x16, 0x1c, 0x8f, 0x73, 0xfc, 0xa4, 0x4d, 0x10, 0x5e, 0x6c, 0x1b, 0xfc, 0x2c, 0xa7, 0xc7, - 0x71, 0xd8, 0x96, 0x95, 0x2c, 0xd2, 0x38, 0xbb, 0x45, 0xfb, 0xdf, 0xf5, 0xc0, 0x54, 0x5e, 0xd4, - 0x34, 0xe6, 0x69, 0xe4, 0xdc, 0xad, 0x6c, 0x93, 0x3b, 0xc2, 0x9f, 0x23, 0xf6, 0x34, 0xe2, 0xc5, - 0x58, 0xc2, 0x93, 0x69, 0x9d, 0x0a, 0x5d, 0xa6, 0x75, 0xda, 0x82, 0x89, 0x3b, 0x5b, 0xc4, 0x5b, - 0xf7, 0x42, 0x27, 0x72, 0xc3, 0x0d, 0x97, 0x29, 0xd0, 0xf9, 0xba, 0x79, 0x45, 0x7a, 0x5d, 0xdc, - 0x4a, 0x22, 0x1c, 0xec, 0x95, 0xce, 0x18, 0x05, 0x71, 0x97, 0xf9, 0x41, 0x82, 0xd3, 0x44, 0xd3, - 0x59, 0xb1, 0x7a, 0x1e, 0x72, 0x56, 0xac, 0x86, 0x2b, 0xcc, 0x6e, 0xa4, 0x1b, 0x09, 0x7b, 0xb6, - 0xae, 0xa8, 0x52, 0xac, 0x61, 0xa0, 0x4f, 0x01, 0xd2, 0xd3, 0x1a, 0x1a, 0x41, 0x6b, 0x9f, 0xdb, - 0xdf, 0x2b, 0xa1, 0xd5, 0x14, 0xf4, 0x60, 0xaf, 0x34, 0x49, 0x4b, 0x97, 0x3d, 0xfa, 0xfc, 0x8d, - 0x23, 0xfd, 0x65, 0x10, 0x42, 0xb7, 0x60, 0x9c, 0x96, 0xb2, 0x1d, 0x25, 0x23, 0xe2, 0xf2, 0x27, - 0xeb, 0x33, 0xfb, 0x7b, 0xa5, 0xf1, 0xd5, 0x04, 0x2c, 0x8f, 0x74, 0x8a, 0x48, 0x46, 0x72, 0xac, - 0x81, 0x6e, 0x93, 0x63, 0xd9, 0x5f, 0xb4, 0xe0, 0x14, 0xbd, 0xe0, 0x6a, 0xd7, 0x73, 0xb4, 0xe8, - 0x4e, 0xd3, 0xe5, 0x7a, 0x1a, 0x71, 0xd5, 0x30, 0x59, 0x5d, 0x79, 0x99, 0x6b, 0x69, 0x14, 0x94, - 0x9e, 0xf0, 0xdb, 0xae, 0x57, 0x4b, 0x9e, 0xf0, 0xd7, 0x5c, 0xaf, 0x86, 0x19, 0x44, 0x5d, 0x59, - 0xc5, 0xdc, 0x08, 0xfb, 0x5f, 0xa3, 0x7b, 0x95, 0xf6, 0xe5, 0x3b, 0xda, 0x0d, 0xf4, 0x8c, 0xae, - 0x53, 0x15, 0xe6, 0x93, 0xb9, 0xfa, 0xd4, 0x2f, 0x58, 0x20, 0xbc, 0xdf, 0xbb, 0xb8, 0x93, 0xdf, - 0x86, 0xe1, 0x9d, 0x74, 0xca, 0xd7, 0x73, 0xf9, 0xe1, 0x00, 0x44, 0xa2, 0x57, 0xc5, 0xa2, 0x1b, - 0xe9, 0x5d, 0x0d, 0x5a, 0x76, 0x0d, 0x04, 0x74, 0x81, 0x30, 0xad, 0x46, 0xe7, 0xde, 0x3c, 0x0f, - 0x50, 0x63, 0xb8, 0x2c, 0x0f, 0x7c, 0xc1, 0xe4, 0xb8, 0x16, 0x14, 0x04, 0x6b, 0x58, 0xf6, 0xaf, - 0x16, 0x61, 0x48, 0xa6, 0x18, 0x6d, 0x79, 0xdd, 0xc8, 0x1e, 0x75, 0xc6, 0xa9, 0xd0, 0x91, 0x71, - 0x7a, 0x07, 0x26, 0x02, 0x52, 0x6d, 0x05, 0xa1, 0xbb, 0x43, 0x24, 0x58, 0x6c, 0x92, 0x19, 0x9e, - 0xe0, 0x21, 0x01, 0x3c, 0x60, 0x21, 0xb2, 0x12, 0x85, 0x4c, 0x69, 0x9c, 0x26, 0x84, 0x2e, 0xc2, - 0x20, 0x13, 0xbd, 0x97, 0x63, 0x81, 0xb0, 0x12, 0x7c, 0xad, 0x48, 0x00, 0x8e, 0x71, 0xd8, 0xe3, - 0xa0, 0x75, 0x9b, 0xa1, 0x27, 0x3c, 0xc1, 0x2b, 0xbc, 0x18, 0x4b, 0x38, 0xfa, 0x38, 0x8c, 0xf3, - 0x7a, 0x81, 0xdf, 0x74, 0x36, 0xb9, 0x4a, 0xb0, 0x57, 0x85, 0xd7, 0x19, 0x5f, 0x49, 0xc0, 0x0e, - 0xf6, 0x4a, 0xc7, 0x92, 0x65, 0xac, 0xdb, 0x29, 0x2a, 0xcc, 0xf2, 0x8f, 0x37, 0x42, 0xef, 0x8c, - 0x94, 0xc1, 0x60, 0x0c, 0xc2, 0x3a, 0x9e, 0xfd, 0xcf, 0x16, 0x4c, 0x68, 0x53, 0xd5, 0x75, 0x8e, - 0x0d, 0x63, 0x90, 0x0a, 0x5d, 0x0c, 0xd2, 0xe1, 0xa2, 0x3d, 0x64, 0xce, 0x70, 0xcf, 0x03, 0x9a, - 0x61, 0xfb, 0x33, 0x80, 0xd2, 0xf9, 0x6b, 0xd1, 0x9b, 0xdc, 0x90, 0xdf, 0x0d, 0x48, 0xad, 0x9d, - 0xc2, 0x5f, 0x8f, 0x9c, 0x23, 0x3d, 0x57, 0x79, 0x2d, 0xac, 0xea, 0xdb, 0x3f, 0xde, 0x03, 0xe3, - 0xc9, 0x58, 0x1d, 0xe8, 0x2a, 0xf4, 0x71, 0x2e, 0x5d, 0x90, 0x6f, 0x63, 0x4f, 0xa6, 0x45, 0xf8, - 0xe0, 0xf9, 0x6f, 0x38, 0x77, 0x2f, 0xea, 0xa3, 0x77, 0x60, 0xa8, 0xe6, 0xdf, 0xf1, 0xee, 0x38, - 0x41, 0x6d, 0xb6, 0xbc, 0x2c, 0x4e, 0x88, 0x4c, 0x01, 0xd4, 0x42, 0x8c, 0xa6, 0x47, 0x0d, 0x61, - 0xb6, 0x13, 0x31, 0x08, 0xeb, 0xe4, 0xd0, 0x1a, 0x4b, 0xc9, 0xb4, 0xe1, 0x6e, 0xae, 0x38, 0xcd, - 0x76, 0x5e, 0x5d, 0xf3, 0x12, 0x49, 0xa3, 0x3c, 0x22, 0xf2, 0x36, 0x71, 0x00, 0x8e, 0x09, 0xa1, - 0xcf, 0xc1, 0x64, 0x98, 0xa3, 0x12, 0xcb, 0x4b, 0x67, 0xde, 0x4e, 0x4b, 0xc4, 0x85, 0x29, 0x59, - 0xca, 0xb3, 0xac, 0x66, 0xd0, 0x5d, 0x40, 0x42, 0xf4, 0xbc, 0x16, 0xb4, 0xc2, 0x68, 0xae, 0xe5, - 0xd5, 0xea, 0x32, 0x65, 0xd3, 0x87, 0xb3, 0xe5, 0x04, 0x49, 0x6c, 0xad, 0x6d, 0x16, 0x12, 0x38, - 0x8d, 0x81, 0x33, 0xda, 0xb0, 0xbf, 0xd0, 0x03, 0xd3, 0x32, 0x61, 0x74, 0x86, 0xf7, 0xca, 0xe7, - 0xad, 0x84, 0xfb, 0xca, 0x2b, 0xf9, 0x07, 0xfd, 0x43, 0x73, 0x62, 0xf9, 0x52, 0xda, 0x89, 0xe5, - 0xb5, 0x43, 0x76, 0xe3, 0x81, 0xb9, 0xb2, 0x7c, 0xcf, 0xfa, 0x9f, 0xec, 0x1f, 0x03, 0xe3, 0x6a, - 0x46, 0x98, 0xc7, 0x5b, 0x2f, 0x4b, 0xd5, 0x51, 0xce, 0xf3, 0xff, 0xaa, 0xc0, 0x31, 0x2e, 0xfb, - 0x61, 0x19, 0x95, 0x9d, 0x9d, 0xb3, 0x8a, 0x0e, 0xa5, 0x49, 0x1a, 0xcd, 0x68, 0x77, 0xc1, 0x0d, - 0x44, 0x8f, 0x33, 0x69, 0x2e, 0x0a, 0x9c, 0x34, 0x4d, 0x09, 0xc1, 0x8a, 0x0e, 0xda, 0x81, 0x89, - 0x4d, 0x16, 0xf1, 0x49, 0xcb, 0xdd, 0x2c, 0xce, 0x85, 0xcc, 0x7d, 0x7b, 0x65, 0x7e, 0x31, 0x3f, - 0xd1, 0x33, 0x7f, 0xfc, 0xa5, 0x50, 0x70, 0xba, 0x09, 0xba, 0x35, 0x8e, 0x39, 0x77, 0xc2, 0xc5, - 0xba, 0x13, 0x46, 0x6e, 0x75, 0xae, 0xee, 0x57, 0xb7, 0x2b, 0x91, 0x1f, 0xc8, 0x04, 0x8f, 0x99, - 0x6f, 0xaf, 0xd9, 0x5b, 0x95, 0x14, 0xbe, 0xd1, 0xfc, 0xd4, 0xfe, 0x5e, 0xe9, 0x58, 0x16, 0x16, - 0xce, 0x6c, 0x0b, 0xad, 0x42, 0xff, 0xa6, 0x1b, 0x61, 0xd2, 0xf4, 0xc5, 0x69, 0x91, 0x79, 0x14, - 0x5e, 0xe1, 0x28, 0x46, 0x4b, 0x2c, 0x22, 0x95, 0x00, 0x60, 0x49, 0x04, 0xbd, 0xa9, 0x2e, 0x81, - 0xbe, 0x7c, 0x01, 0x6c, 0xda, 0xf6, 0x2e, 0xf3, 0x1a, 0x78, 0x1d, 0x8a, 0xde, 0x46, 0xd8, 0x2e, - 0x16, 0xcf, 0xea, 0x92, 0x21, 0x3f, 0x9b, 0xeb, 0xa7, 0x4f, 0xe3, 0xd5, 0xa5, 0x0a, 0xa6, 0x15, - 0x99, 0xdb, 0x6b, 0x58, 0x0d, 0x5d, 0x91, 0x2c, 0x2a, 0xd3, 0x0b, 0x78, 0xb9, 0x32, 0x5f, 0x59, - 0x36, 0x68, 0xb0, 0xa8, 0x86, 0xac, 0x18, 0xf3, 0xea, 0xe8, 0x26, 0x0c, 0x6e, 0xf2, 0x83, 0x6f, - 0x23, 0x14, 0x49, 0xe3, 0x33, 0x2f, 0xa3, 0x2b, 0x12, 0xc9, 0xa0, 0xc7, 0xae, 0x0c, 0x05, 0xc2, - 0x31, 0x29, 0xf4, 0x05, 0x0b, 0x8e, 0x27, 0xb3, 0xee, 0x33, 0x67, 0x35, 0x61, 0xa6, 0x96, 0xe9, - 0x00, 0x50, 0xce, 0xaa, 0x60, 0x34, 0xc8, 0xd4, 0x2f, 0x99, 0x68, 0x38, 0xbb, 0x39, 0x3a, 0xd0, - 0xc1, 0xed, 0x5a, 0xbb, 0xfc, 0x42, 0x89, 0xc0, 0x44, 0x7c, 0xa0, 0xf1, 0xdc, 0x02, 0xa6, 0x15, - 0xd1, 0x1a, 0xc0, 0x46, 0x9d, 0x88, 0x88, 0x8f, 0xc2, 0x28, 0x2a, 0xf3, 0xf6, 0x5f, 0x52, 0x58, - 0x82, 0x0e, 0x7b, 0x89, 0xc6, 0xa5, 0x58, 0xa3, 0x43, 0x97, 0x52, 0xd5, 0xf5, 0x6a, 0x24, 0x60, - 0xca, 0xad, 0x9c, 0xa5, 0x34, 0xcf, 0x30, 0xd2, 0x4b, 0x89, 0x97, 0x63, 0x41, 0x81, 0xd1, 0x22, - 0xcd, 0xad, 0x8d, 0xb0, 0x5d, 0x26, 0x8b, 0x79, 0xd2, 0xdc, 0x4a, 0x2c, 0x28, 0x4e, 0x8b, 0x95, - 0x63, 0x41, 0x81, 0x6e, 0x99, 0x0d, 0xba, 0x81, 0x48, 0x30, 0x35, 0x96, 0xbf, 0x65, 0x96, 0x38, - 0x4a, 0x7a, 0xcb, 0x08, 0x00, 0x96, 0x44, 0xd0, 0xa7, 0x4d, 0x6e, 0x67, 0x9c, 0xd1, 0x7c, 0xa6, - 0x03, 0xb7, 0x63, 0xd0, 0x6d, 0xcf, 0xef, 0xbc, 0x02, 0x85, 0x8d, 0x2a, 0x53, 0x8a, 0xe5, 0xe8, - 0x0c, 0x96, 0xe6, 0x0d, 0x6a, 0x2c, 0x32, 0xfc, 0xd2, 0x3c, 0x2e, 0x6c, 0x54, 0xe9, 0xd2, 0x77, - 0xee, 0xb5, 0x02, 0xb2, 0xe4, 0xd6, 0x89, 0xc8, 0x6a, 0x91, 0xb9, 0xf4, 0x67, 0x25, 0x52, 0x7a, - 0xe9, 0x2b, 0x10, 0x8e, 0x49, 0x51, 0xba, 0x31, 0x0f, 0x36, 0x99, 0x4f, 0x57, 0xb1, 0x5a, 0x69, - 0xba, 0x99, 0x5c, 0xd8, 0x36, 0x8c, 0xec, 0x84, 0xcd, 0x2d, 0x22, 0x4f, 0x45, 0xa6, 0xae, 0xcb, - 0x89, 0x54, 0x71, 0x53, 0x20, 0xba, 0x41, 0xd4, 0x72, 0xea, 0xa9, 0x83, 0x9c, 0x89, 0x56, 0x6e, - 0xea, 0xc4, 0xb0, 0x49, 0x9b, 0x2e, 0x84, 0x77, 0x79, 0x38, 0x39, 0xa6, 0xb8, 0xcb, 0x59, 0x08, - 0x19, 0x11, 0xe7, 0xf8, 0x42, 0x10, 0x00, 0x2c, 0x89, 0xa8, 0xc1, 0x66, 0x17, 0xd0, 0x89, 0x0e, - 0x83, 0x9d, 0xea, 0x6f, 0x3c, 0xd8, 0xec, 0xc2, 0x89, 0x49, 0xb1, 0x8b, 0xa6, 0xb9, 0xe5, 0x47, - 0xbe, 0x97, 0xb8, 0xe4, 0x4e, 0xe6, 0x5f, 0x34, 0xe5, 0x0c, 0xfc, 0xf4, 0x45, 0x93, 0x85, 0x85, - 0x33, 0xdb, 0xa2, 0x1f, 0xd7, 0x94, 0x91, 0x01, 0x45, 0xe6, 0x8d, 0xa7, 0x72, 0x02, 0x6b, 0xa6, - 0xc3, 0x07, 0xf2, 0x8f, 0x53, 0x20, 0x1c, 0x93, 0x42, 0x35, 0x18, 0x6d, 0x1a, 0x11, 0x67, 0x59, - 0x06, 0x91, 0x1c, 0xbe, 0x20, 0x2b, 0x36, 0x2d, 0x97, 0x10, 0x99, 0x10, 0x9c, 0xa0, 0xc9, 0x2c, - 0xf7, 0xb8, 0xab, 0x1f, 0x4b, 0x30, 0x92, 0x33, 0xd5, 0x19, 0xde, 0x80, 0x7c, 0xaa, 0x05, 0x00, - 0x4b, 0x22, 0x74, 0x34, 0x84, 0x83, 0x9a, 0x1f, 0xb2, 0x3c, 0x3d, 0x79, 0x0a, 0xf6, 0x2c, 0x35, - 0x91, 0x0c, 0xb3, 0x2e, 0x40, 0x38, 0x26, 0x45, 0x4f, 0x72, 0x7a, 0xe1, 0x9d, 0xce, 0x3f, 0xc9, - 0x93, 0xd7, 0x1d, 0x3b, 0xc9, 0xe9, 0x65, 0x57, 0x14, 0x57, 0x9d, 0x8a, 0x0a, 0xce, 0x72, 0x8c, - 0xe4, 0xf4, 0x4b, 0x85, 0x15, 0x4f, 0xf7, 0x4b, 0x81, 0x70, 0x4c, 0x8a, 0x5d, 0xc5, 0x2c, 0x34, - 0xdd, 0xd9, 0x36, 0x57, 0x31, 0x45, 0xc8, 0xb8, 0x8a, 0xb5, 0xd0, 0x75, 0xf6, 0x8f, 0x17, 0xe0, - 0x6c, 0xfb, 0x7d, 0x1b, 0xeb, 0xd0, 0xca, 0xb1, 0xcd, 0x52, 0x42, 0x87, 0xc6, 0x25, 0x3a, 0x31, - 0x56, 0xd7, 0x01, 0x87, 0xaf, 0xc0, 0x84, 0x72, 0x47, 0xac, 0xbb, 0xd5, 0x5d, 0x2d, 0xb1, 0xa8, - 0x0a, 0xcd, 0x53, 0x49, 0x22, 0xe0, 0x74, 0x1d, 0x34, 0x0b, 0x63, 0x46, 0xe1, 0xf2, 0x82, 0x78, - 0xfe, 0xc7, 0xd9, 0x31, 0x4c, 0x30, 0x4e, 0xe2, 0xdb, 0xbf, 0x66, 0xc1, 0xc9, 0x9c, 0x3c, 0xf3, - 0x5d, 0xc7, 0xd3, 0xdd, 0x80, 0xb1, 0xa6, 0x59, 0xb5, 0x43, 0x08, 0x70, 0x23, 0x9b, 0xbd, 0xea, - 0x6b, 0x02, 0x80, 0x93, 0x44, 0xed, 0x5f, 0x29, 0xc0, 0x99, 0xb6, 0xf6, 0xf5, 0x08, 0xc3, 0x89, - 0xcd, 0x46, 0xe8, 0xcc, 0x07, 0xa4, 0x46, 0xbc, 0xc8, 0x75, 0xea, 0x95, 0x26, 0xa9, 0x6a, 0x5a, - 0x50, 0x66, 0xa8, 0x7e, 0x65, 0xa5, 0x32, 0x9b, 0xc6, 0xc0, 0x39, 0x35, 0xd1, 0x12, 0xa0, 0x34, - 0x44, 0xcc, 0x30, 0x7b, 0xe2, 0xa6, 0xe9, 0xe1, 0x8c, 0x1a, 0xe8, 0x65, 0x18, 0x51, 0x76, 0xfb, - 0xda, 0x8c, 0xb3, 0x0b, 0x02, 0xeb, 0x00, 0x6c, 0xe2, 0xa1, 0x4b, 0x3c, 0x6d, 0x92, 0x48, 0xb0, - 0x25, 0x54, 0xa6, 0x63, 0x32, 0x27, 0x92, 0x28, 0xc6, 0x3a, 0xce, 0xdc, 0xe5, 0x3f, 0xfd, 0xf6, - 0xd9, 0x0f, 0xfd, 0xc5, 0xb7, 0xcf, 0x7e, 0xe8, 0xaf, 0xbe, 0x7d, 0xf6, 0x43, 0x3f, 0xb4, 0x7f, - 0xd6, 0xfa, 0xd3, 0xfd, 0xb3, 0xd6, 0x5f, 0xec, 0x9f, 0xb5, 0xfe, 0x6a, 0xff, 0xac, 0xf5, 0xff, - 0xee, 0x9f, 0xb5, 0xbe, 0xfc, 0xb7, 0x67, 0x3f, 0xf4, 0x36, 0x8a, 0x23, 0x54, 0x5f, 0xa4, 0xb3, - 0x73, 0x71, 0xe7, 0xd2, 0x7f, 0x0a, 0x00, 0x00, 0xff, 0xff, 0x60, 0x45, 0x7a, 0xd6, 0xa3, 0x24, - 0x01, 0x00, + // 16206 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xbd, 0x69, 0x90, 0x1c, 0xc9, + 0x75, 0x30, 0xc6, 0xea, 0x9e, 0xf3, 0xcd, 0x9d, 0xb8, 0x06, 0xb3, 0x00, 0x1a, 0x5b, 0xbb, 0x8b, + 0xc5, 0x5e, 0x03, 0x62, 0x0f, 0x2e, 0xb8, 0xbb, 0x5c, 0xed, 0x9c, 0x40, 0x2f, 0x30, 0x83, 0xde, + 0xec, 0x01, 0x40, 0x2e, 0x97, 0x14, 0x0b, 0xdd, 0x39, 0x33, 0xc5, 0xe9, 0xae, 0xea, 0xad, 0xaa, + 0x1e, 0x60, 0x60, 0x2a, 0x24, 0x51, 0x16, 0x25, 0x52, 0x72, 0x04, 0x43, 0x21, 0x59, 0x0e, 0x4a, + 0xa1, 0x1f, 0xba, 0x65, 0x5a, 0xb2, 0x68, 0xc9, 0x92, 0x2c, 0xea, 0xb2, 0x2d, 0x47, 0xc8, 0xfe, + 0x21, 0x4b, 0x8a, 0x30, 0xa9, 0xb0, 0xc2, 0x23, 0x73, 0x6c, 0x87, 0x42, 0x3f, 0x2c, 0x29, 0x64, + 0xff, 0xb0, 0x27, 0xf4, 0x7d, 0xfc, 0x22, 0xcf, 0xca, 0xac, 0xa3, 0xbb, 0x07, 0x0b, 0x0c, 0x97, + 0x8c, 0xfd, 0xd7, 0x9d, 0xef, 0xe5, 0xcb, 0xac, 0x3c, 0x5f, 0xbe, 0x13, 0xec, 0xad, 0x4b, 0xe1, + 0xac, 0xeb, 0x5f, 0x70, 0x5a, 0xee, 0x85, 0x9a, 0x1f, 0x90, 0x0b, 0xdb, 0x17, 0x2f, 0x6c, 0x10, + 0x8f, 0x04, 0x4e, 0x44, 0xea, 0xb3, 0xad, 0xc0, 0x8f, 0x7c, 0x84, 0x38, 0xce, 0xac, 0xd3, 0x72, + 0x67, 0x29, 0xce, 0xec, 0xf6, 0xc5, 0x99, 0xe7, 0x36, 0xdc, 0x68, 0xb3, 0x7d, 0x7b, 0xb6, 0xe6, + 0x37, 0x2f, 0x6c, 0xf8, 0x1b, 0xfe, 0x05, 0x86, 0x7a, 0xbb, 0xbd, 0xce, 0xfe, 0xb1, 0x3f, 0xec, + 0x17, 0x27, 0x31, 0xf3, 0x62, 0xdc, 0x4c, 0xd3, 0xa9, 0x6d, 0xba, 0x1e, 0x09, 0x76, 0x2e, 0xb4, + 0xb6, 0x36, 0x58, 0xbb, 0x01, 0x09, 0xfd, 0x76, 0x50, 0x23, 0xc9, 0x86, 0x3b, 0xd6, 0x0a, 0x2f, + 0x34, 0x49, 0xe4, 0x64, 0x74, 0x77, 0xe6, 0x42, 0x5e, 0xad, 0xa0, 0xed, 0x45, 0x6e, 0x33, 0xdd, + 0xcc, 0x47, 0xba, 0x55, 0x08, 0x6b, 0x9b, 0xa4, 0xe9, 0xa4, 0xea, 0xbd, 0x90, 0x57, 0xaf, 0x1d, + 0xb9, 0x8d, 0x0b, 0xae, 0x17, 0x85, 0x51, 0x90, 0xac, 0x64, 0x7f, 0xd3, 0x82, 0xb3, 0x73, 0xb7, + 0xaa, 0x4b, 0x0d, 0x27, 0x8c, 0xdc, 0xda, 0x7c, 0xc3, 0xaf, 0x6d, 0x55, 0x23, 0x3f, 0x20, 0x37, + 0xfd, 0x46, 0xbb, 0x49, 0xaa, 0x6c, 0x20, 0xd0, 0xb3, 0x30, 0xb4, 0xcd, 0xfe, 0x97, 0x17, 0xa7, + 0xad, 0xb3, 0xd6, 0xf9, 0xe1, 0xf9, 0xc9, 0xbf, 0xd8, 0x2d, 0x7d, 0x68, 0x6f, 0xb7, 0x34, 0x74, + 0x53, 0x94, 0x63, 0x85, 0x81, 0xce, 0xc1, 0xc0, 0x7a, 0xb8, 0xb6, 0xd3, 0x22, 0xd3, 0x05, 0x86, + 0x3b, 0x2e, 0x70, 0x07, 0x96, 0xab, 0xb4, 0x14, 0x0b, 0x28, 0xba, 0x00, 0xc3, 0x2d, 0x27, 0x88, + 0xdc, 0xc8, 0xf5, 0xbd, 0xe9, 0xe2, 0x59, 0xeb, 0x7c, 0xff, 0xfc, 0x94, 0x40, 0x1d, 0xae, 0x48, + 0x00, 0x8e, 0x71, 0x68, 0x37, 0x02, 0xe2, 0xd4, 0xaf, 0x7b, 0x8d, 0x9d, 0xe9, 0xbe, 0xb3, 0xd6, + 0xf9, 0xa1, 0xb8, 0x1b, 0x58, 0x94, 0x63, 0x85, 0x61, 0x7f, 0xa5, 0x00, 0x43, 0x73, 0xeb, 0xeb, + 0xae, 0xe7, 0x46, 0x3b, 0xe8, 0x26, 0x8c, 0x7a, 0x7e, 0x9d, 0xc8, 0xff, 0xec, 0x2b, 0x46, 0x9e, + 0x3f, 0x3b, 0x9b, 0x5e, 0x4a, 0xb3, 0xab, 0x1a, 0xde, 0xfc, 0xe4, 0xde, 0x6e, 0x69, 0x54, 0x2f, + 0xc1, 0x06, 0x1d, 0x84, 0x61, 0xa4, 0xe5, 0xd7, 0x15, 0xd9, 0x02, 0x23, 0x5b, 0xca, 0x22, 0x5b, + 0x89, 0xd1, 0xe6, 0x27, 0xf6, 0x76, 0x4b, 0x23, 0x5a, 0x01, 0xd6, 0x89, 0xa0, 0xdb, 0x30, 0x41, + 0xff, 0x7a, 0x91, 0xab, 0xe8, 0x16, 0x19, 0xdd, 0xc7, 0xf2, 0xe8, 0x6a, 0xa8, 0xf3, 0x47, 0xf6, + 0x76, 0x4b, 0x13, 0x89, 0x42, 0x9c, 0x24, 0x68, 0xff, 0xa4, 0x05, 0x13, 0x73, 0xad, 0xd6, 0x5c, + 0xd0, 0xf4, 0x83, 0x4a, 0xe0, 0xaf, 0xbb, 0x0d, 0x82, 0x5e, 0x86, 0xbe, 0x88, 0xce, 0x1a, 0x9f, + 0xe1, 0xc7, 0xc4, 0xd0, 0xf6, 0xd1, 0xb9, 0xda, 0xdf, 0x2d, 0x1d, 0x49, 0xa0, 0xb3, 0xa9, 0x64, + 0x15, 0xd0, 0x1b, 0x30, 0xd9, 0xf0, 0x6b, 0x4e, 0x63, 0xd3, 0x0f, 0x23, 0x01, 0x15, 0x53, 0x7f, + 0x74, 0x6f, 0xb7, 0x34, 0x79, 0x2d, 0x01, 0xc3, 0x29, 0x6c, 0xfb, 0x1e, 0x8c, 0xcf, 0x45, 0x91, + 0x53, 0xdb, 0x24, 0x75, 0xbe, 0xa0, 0xd0, 0x8b, 0xd0, 0xe7, 0x39, 0x4d, 0xd9, 0x99, 0xb3, 0xb2, + 0x33, 0xab, 0x4e, 0x93, 0x76, 0x66, 0xf2, 0x86, 0xe7, 0xbe, 0xdb, 0x16, 0x8b, 0x94, 0x96, 0x61, + 0x86, 0x8d, 0x9e, 0x07, 0xa8, 0x93, 0x6d, 0xb7, 0x46, 0x2a, 0x4e, 0xb4, 0x29, 0xfa, 0x80, 0x44, + 0x5d, 0x58, 0x54, 0x10, 0xac, 0x61, 0xd9, 0x77, 0x61, 0x78, 0x6e, 0xdb, 0x77, 0xeb, 0x15, 0xbf, + 0x1e, 0xa2, 0x2d, 0x98, 0x68, 0x05, 0x64, 0x9d, 0x04, 0xaa, 0x68, 0xda, 0x3a, 0x5b, 0x3c, 0x3f, + 0xf2, 0xfc, 0xf9, 0xcc, 0xb1, 0x37, 0x51, 0x97, 0xbc, 0x28, 0xd8, 0x99, 0x3f, 0x21, 0xda, 0x9b, + 0x48, 0x40, 0x71, 0x92, 0xb2, 0xfd, 0xe7, 0x05, 0x38, 0x36, 0x77, 0xaf, 0x1d, 0x90, 0x45, 0x37, + 0xdc, 0x4a, 0x6e, 0xb8, 0xba, 0x1b, 0x6e, 0xad, 0xc6, 0x23, 0xa0, 0x56, 0xfa, 0xa2, 0x28, 0xc7, + 0x0a, 0x03, 0x3d, 0x07, 0x83, 0xf4, 0xf7, 0x0d, 0x5c, 0x16, 0x9f, 0x7c, 0x44, 0x20, 0x8f, 0x2c, + 0x3a, 0x91, 0xb3, 0xc8, 0x41, 0x58, 0xe2, 0xa0, 0x15, 0x18, 0xa9, 0xb1, 0xf3, 0x61, 0x63, 0xc5, + 0xaf, 0x13, 0xb6, 0xb6, 0x86, 0xe7, 0x9f, 0xa1, 0xe8, 0x0b, 0x71, 0xf1, 0xfe, 0x6e, 0x69, 0x9a, + 0xf7, 0x4d, 0x90, 0xd0, 0x60, 0x58, 0xaf, 0x8f, 0x6c, 0xb5, 0xdd, 0xfb, 0x18, 0x25, 0xc8, 0xd8, + 0xea, 0xe7, 0xb5, 0x9d, 0xdb, 0xcf, 0x76, 0xee, 0x68, 0xf6, 0xae, 0x45, 0x17, 0xa1, 0x6f, 0xcb, + 0xf5, 0xea, 0xd3, 0x03, 0x8c, 0xd6, 0x69, 0x3a, 0xe7, 0x57, 0x5d, 0xaf, 0xbe, 0xbf, 0x5b, 0x9a, + 0x32, 0xba, 0x43, 0x0b, 0x31, 0x43, 0xb5, 0xff, 0x1f, 0x0b, 0x4a, 0x0c, 0xb6, 0xec, 0x36, 0x48, + 0x85, 0x04, 0xa1, 0x1b, 0x46, 0xc4, 0x8b, 0x8c, 0x01, 0x7d, 0x1e, 0x20, 0x24, 0xb5, 0x80, 0x44, + 0xda, 0x90, 0xaa, 0x85, 0x51, 0x55, 0x10, 0xac, 0x61, 0xd1, 0xf3, 0x29, 0xdc, 0x74, 0x02, 0xb6, + 0xbe, 0xc4, 0xc0, 0xaa, 0xf3, 0xa9, 0x2a, 0x01, 0x38, 0xc6, 0x31, 0xce, 0xa7, 0x62, 0xb7, 0xf3, + 0x09, 0x7d, 0x0c, 0x26, 0xe2, 0xc6, 0xc2, 0x96, 0x53, 0x93, 0x03, 0xc8, 0x76, 0x70, 0xd5, 0x04, + 0xe1, 0x24, 0xae, 0xfd, 0x9f, 0x5b, 0x62, 0xf1, 0xd0, 0xaf, 0x7e, 0x9f, 0x7f, 0xab, 0xfd, 0x07, + 0x16, 0x0c, 0xce, 0xbb, 0x5e, 0xdd, 0xf5, 0x36, 0xd0, 0x67, 0x60, 0x88, 0x5e, 0x95, 0x75, 0x27, + 0x72, 0xc4, 0x31, 0xfc, 0x61, 0x6d, 0x6f, 0xa9, 0x9b, 0x6b, 0xb6, 0xb5, 0xb5, 0x41, 0x0b, 0xc2, + 0x59, 0x8a, 0x4d, 0x77, 0xdb, 0xf5, 0xdb, 0x9f, 0x25, 0xb5, 0x68, 0x85, 0x44, 0x4e, 0xfc, 0x39, + 0x71, 0x19, 0x56, 0x54, 0xd1, 0x55, 0x18, 0x88, 0x9c, 0x60, 0x83, 0x44, 0xe2, 0x3c, 0xce, 0x3c, + 0x37, 0x79, 0x4d, 0x4c, 0x77, 0x24, 0xf1, 0x6a, 0x24, 0xbe, 0xa5, 0xd6, 0x58, 0x55, 0x2c, 0x48, + 0xd8, 0xff, 0x6e, 0x10, 0x4e, 0x2e, 0x54, 0xcb, 0x39, 0xeb, 0xea, 0x1c, 0x0c, 0xd4, 0x03, 0x77, + 0x9b, 0x04, 0x62, 0x9c, 0x15, 0x95, 0x45, 0x56, 0x8a, 0x05, 0x14, 0x5d, 0x82, 0x51, 0x7e, 0x3f, + 0x5e, 0x71, 0xbc, 0x7a, 0x7c, 0x3c, 0x0a, 0xec, 0xd1, 0x9b, 0x1a, 0x0c, 0x1b, 0x98, 0x07, 0x5c, + 0x54, 0xe7, 0x12, 0x9b, 0x31, 0xef, 0xee, 0xfd, 0xa2, 0x05, 0x93, 0xbc, 0x99, 0xb9, 0x28, 0x0a, + 0xdc, 0xdb, 0xed, 0x88, 0x84, 0xd3, 0xfd, 0xec, 0xa4, 0x5b, 0xc8, 0x1a, 0xad, 0xdc, 0x11, 0x98, + 0xbd, 0x99, 0xa0, 0xc2, 0x0f, 0xc1, 0x69, 0xd1, 0xee, 0x64, 0x12, 0x8c, 0x53, 0xcd, 0xa2, 0x1f, + 0xb1, 0x60, 0xa6, 0xe6, 0x7b, 0x51, 0xe0, 0x37, 0x1a, 0x24, 0xa8, 0xb4, 0x6f, 0x37, 0xdc, 0x70, + 0x93, 0xaf, 0x53, 0x4c, 0xd6, 0xd9, 0x49, 0x90, 0x33, 0x87, 0x0a, 0x49, 0xcc, 0xe1, 0x99, 0xbd, + 0xdd, 0xd2, 0xcc, 0x42, 0x2e, 0x29, 0xdc, 0xa1, 0x19, 0xb4, 0x05, 0x88, 0xde, 0xec, 0xd5, 0xc8, + 0xd9, 0x20, 0x71, 0xe3, 0x83, 0xbd, 0x37, 0x7e, 0x7c, 0x6f, 0xb7, 0x84, 0x56, 0x53, 0x24, 0x70, + 0x06, 0x59, 0xf4, 0x2e, 0x1c, 0xa5, 0xa5, 0xa9, 0x6f, 0x1d, 0xea, 0xbd, 0xb9, 0xe9, 0xbd, 0xdd, + 0xd2, 0xd1, 0xd5, 0x0c, 0x22, 0x38, 0x93, 0x34, 0xfa, 0x21, 0x0b, 0x4e, 0xc6, 0x9f, 0xbf, 0x74, + 0xb7, 0xe5, 0x78, 0xf5, 0xb8, 0xe1, 0xe1, 0xde, 0x1b, 0xa6, 0x67, 0xf2, 0xc9, 0x85, 0x3c, 0x4a, + 0x38, 0xbf, 0x11, 0xe4, 0xc1, 0x11, 0xda, 0xb5, 0x64, 0xdb, 0xd0, 0x7b, 0xdb, 0x27, 0xf6, 0x76, + 0x4b, 0x47, 0x56, 0xd3, 0x34, 0x70, 0x16, 0xe1, 0x99, 0x05, 0x38, 0x96, 0xb9, 0x3a, 0xd1, 0x24, + 0x14, 0xb7, 0x08, 0x67, 0x02, 0x87, 0x31, 0xfd, 0x89, 0x8e, 0x42, 0xff, 0xb6, 0xd3, 0x68, 0x8b, + 0x8d, 0x89, 0xf9, 0x9f, 0x57, 0x0a, 0x97, 0x2c, 0xfb, 0x7f, 0x28, 0xc2, 0xc4, 0x42, 0xb5, 0x7c, + 0x5f, 0xbb, 0x5e, 0xbf, 0xf6, 0x0a, 0x1d, 0xaf, 0xbd, 0xf8, 0x12, 0x2d, 0xe6, 0x5e, 0xa2, 0x3f, + 0x98, 0xb1, 0x65, 0xfb, 0xd8, 0x96, 0xfd, 0x68, 0xce, 0x96, 0x7d, 0xc0, 0x1b, 0x75, 0x3b, 0x67, + 0xd5, 0xf6, 0xb3, 0x09, 0xcc, 0xe4, 0x90, 0x18, 0xef, 0x97, 0x3c, 0x6a, 0x0f, 0xb8, 0x74, 0x1f, + 0xcc, 0x3c, 0xd6, 0x60, 0x74, 0xc1, 0x69, 0x39, 0xb7, 0xdd, 0x86, 0x1b, 0xb9, 0x24, 0x44, 0x4f, + 0x42, 0xd1, 0xa9, 0xd7, 0x19, 0x77, 0x37, 0x3c, 0x7f, 0x6c, 0x6f, 0xb7, 0x54, 0x9c, 0xab, 0x53, + 0x36, 0x03, 0x14, 0xd6, 0x0e, 0xa6, 0x18, 0xe8, 0x69, 0xe8, 0xab, 0x07, 0x7e, 0x6b, 0xba, 0xc0, + 0x30, 0xe9, 0x2e, 0xef, 0x5b, 0x0c, 0xfc, 0x56, 0x02, 0x95, 0xe1, 0xd8, 0x7f, 0x56, 0x80, 0x53, + 0x0b, 0xa4, 0xb5, 0xb9, 0x5c, 0xcd, 0xb9, 0x2f, 0xce, 0xc3, 0x50, 0xd3, 0xf7, 0xdc, 0xc8, 0x0f, + 0x42, 0xd1, 0x34, 0x5b, 0x11, 0x2b, 0xa2, 0x0c, 0x2b, 0x28, 0x3a, 0x0b, 0x7d, 0xad, 0x98, 0x89, + 0x1d, 0x95, 0x0c, 0x30, 0x63, 0x5f, 0x19, 0x84, 0x62, 0xb4, 0x43, 0x12, 0x88, 0x15, 0xa3, 0x30, + 0x6e, 0x84, 0x24, 0xc0, 0x0c, 0x12, 0x73, 0x02, 0x94, 0x47, 0x10, 0x37, 0x42, 0x82, 0x13, 0xa0, + 0x10, 0xac, 0x61, 0xa1, 0x0a, 0x0c, 0x87, 0x89, 0x99, 0xed, 0x69, 0x6b, 0x8e, 0x31, 0x56, 0x41, + 0xcd, 0x64, 0x4c, 0xc4, 0xb8, 0xc1, 0x06, 0xba, 0xb2, 0x0a, 0x5f, 0x2f, 0x00, 0xe2, 0x43, 0xf8, + 0x5d, 0x36, 0x70, 0x37, 0xd2, 0x03, 0xd7, 0xfb, 0x96, 0x78, 0x50, 0xa3, 0xf7, 0xff, 0x5a, 0x70, + 0x6a, 0xc1, 0xf5, 0xea, 0x24, 0xc8, 0x59, 0x80, 0x0f, 0xe7, 0x29, 0x7f, 0x30, 0x26, 0xc5, 0x58, + 0x62, 0x7d, 0x0f, 0x60, 0x89, 0xd9, 0xff, 0x6c, 0x01, 0xe2, 0x9f, 0xfd, 0xbe, 0xfb, 0xd8, 0x1b, + 0xe9, 0x8f, 0x7d, 0x00, 0xcb, 0xc2, 0xbe, 0x06, 0xe3, 0x0b, 0x0d, 0x97, 0x78, 0x51, 0xb9, 0xb2, + 0xe0, 0x7b, 0xeb, 0xee, 0x06, 0x7a, 0x05, 0xc6, 0x23, 0xb7, 0x49, 0xfc, 0x76, 0x54, 0x25, 0x35, + 0xdf, 0x63, 0x2f, 0x57, 0xeb, 0x7c, 0xff, 0x3c, 0xda, 0xdb, 0x2d, 0x8d, 0xaf, 0x19, 0x10, 0x9c, + 0xc0, 0xb4, 0x7f, 0x95, 0x9e, 0x5b, 0x8d, 0x76, 0x18, 0x91, 0x60, 0x2d, 0x68, 0x87, 0xd1, 0x7c, + 0x9b, 0xf2, 0x9e, 0x95, 0xc0, 0xa7, 0xdd, 0x71, 0x7d, 0x0f, 0x9d, 0x32, 0x9e, 0xe3, 0x43, 0xf2, + 0x29, 0x2e, 0x9e, 0xdd, 0xb3, 0x00, 0xa1, 0xbb, 0xe1, 0x91, 0x40, 0x7b, 0x3e, 0x8c, 0xb3, 0xad, + 0xa2, 0x4a, 0xb1, 0x86, 0x81, 0x1a, 0x30, 0xd6, 0x70, 0x6e, 0x93, 0x46, 0x95, 0x34, 0x48, 0x2d, + 0xf2, 0x03, 0x21, 0xdf, 0x78, 0xa1, 0xb7, 0x77, 0xc0, 0x35, 0xbd, 0xea, 0xfc, 0xd4, 0xde, 0x6e, + 0x69, 0xcc, 0x28, 0xc2, 0x26, 0x71, 0x7a, 0x74, 0xf8, 0x2d, 0xfa, 0x15, 0x4e, 0x43, 0x7f, 0x7c, + 0x5e, 0x17, 0x65, 0x58, 0x41, 0xd5, 0xd1, 0xd1, 0x97, 0x77, 0x74, 0xd8, 0x7f, 0x47, 0x17, 0x9a, + 0xdf, 0x6c, 0xf9, 0x1e, 0xf1, 0xa2, 0x05, 0xdf, 0xab, 0x73, 0xc9, 0xd4, 0x2b, 0x86, 0xe8, 0xe4, + 0x5c, 0x42, 0x74, 0x72, 0x3c, 0x5d, 0x43, 0x93, 0x9e, 0x7c, 0x14, 0x06, 0xc2, 0xc8, 0x89, 0xda, + 0xa1, 0x18, 0xb8, 0x47, 0xe5, 0xb2, 0xab, 0xb2, 0xd2, 0xfd, 0xdd, 0xd2, 0x84, 0xaa, 0xc6, 0x8b, + 0xb0, 0xa8, 0x80, 0x9e, 0x82, 0xc1, 0x26, 0x09, 0x43, 0x67, 0x43, 0xb2, 0x0d, 0x13, 0xa2, 0xee, + 0xe0, 0x0a, 0x2f, 0xc6, 0x12, 0x8e, 0x1e, 0x83, 0x7e, 0x12, 0x04, 0x7e, 0x20, 0xbe, 0x6d, 0x4c, + 0x20, 0xf6, 0x2f, 0xd1, 0x42, 0xcc, 0x61, 0xf6, 0xff, 0x6c, 0xc1, 0x84, 0xea, 0x2b, 0x6f, 0xeb, + 0x10, 0x9e, 0x6b, 0x6f, 0x03, 0xd4, 0xe4, 0x07, 0x86, 0xec, 0x9a, 0x1d, 0x79, 0xfe, 0x5c, 0x26, + 0x47, 0x93, 0x1a, 0xc6, 0x98, 0xb2, 0x2a, 0x0a, 0xb1, 0x46, 0xcd, 0xfe, 0x63, 0x0b, 0x8e, 0x24, + 0xbe, 0xe8, 0x9a, 0x1b, 0x46, 0xe8, 0x9d, 0xd4, 0x57, 0xcd, 0xf6, 0xb8, 0xf8, 0xdc, 0x90, 0x7f, + 0x93, 0xda, 0xf3, 0xb2, 0x44, 0xfb, 0xa2, 0x2b, 0xd0, 0xef, 0x46, 0xa4, 0x29, 0x3f, 0xe6, 0xb1, + 0x8e, 0x1f, 0xc3, 0x7b, 0x15, 0xcf, 0x48, 0x99, 0xd6, 0xc4, 0x9c, 0x80, 0xfd, 0x67, 0x45, 0x18, + 0xe6, 0xfb, 0x7b, 0xc5, 0x69, 0x1d, 0xc2, 0x5c, 0x3c, 0x03, 0xc3, 0x6e, 0xb3, 0xd9, 0x8e, 0x9c, + 0xdb, 0xe2, 0xde, 0x1b, 0xe2, 0x67, 0x50, 0x59, 0x16, 0xe2, 0x18, 0x8e, 0xca, 0xd0, 0xc7, 0xba, + 0xc2, 0xbf, 0xf2, 0xc9, 0xec, 0xaf, 0x14, 0x7d, 0x9f, 0x5d, 0x74, 0x22, 0x87, 0xb3, 0x9c, 0x6a, + 0x5f, 0xd1, 0x22, 0xcc, 0x48, 0x20, 0x07, 0xe0, 0xb6, 0xeb, 0x39, 0xc1, 0x0e, 0x2d, 0x9b, 0x2e, + 0x32, 0x82, 0xcf, 0x75, 0x26, 0x38, 0xaf, 0xf0, 0x39, 0x59, 0xf5, 0x61, 0x31, 0x00, 0x6b, 0x44, + 0x67, 0x5e, 0x86, 0x61, 0x85, 0x7c, 0x10, 0xce, 0x71, 0xe6, 0x63, 0x30, 0x91, 0x68, 0xab, 0x5b, + 0xf5, 0x51, 0x9d, 0xf1, 0xfc, 0x43, 0x76, 0x64, 0x88, 0x5e, 0x2f, 0x79, 0xdb, 0xe2, 0x6e, 0xba, + 0x07, 0x47, 0x1b, 0x19, 0x47, 0xbe, 0x98, 0xd7, 0xde, 0xaf, 0x88, 0x53, 0xe2, 0xb3, 0x8f, 0x66, + 0x41, 0x71, 0x66, 0x1b, 0xc6, 0x89, 0x58, 0xe8, 0x74, 0x22, 0xd2, 0xf3, 0xee, 0xa8, 0xea, 0xfc, + 0x55, 0xb2, 0xa3, 0x0e, 0xd5, 0xef, 0x64, 0xf7, 0x4f, 0xf3, 0xd1, 0xe7, 0xc7, 0xe5, 0x88, 0x20, + 0x50, 0xbc, 0x4a, 0x76, 0xf8, 0x54, 0xe8, 0x5f, 0x57, 0xec, 0xf8, 0x75, 0x5f, 0xb3, 0x60, 0x4c, + 0x7d, 0xdd, 0x21, 0x9c, 0x0b, 0xf3, 0xe6, 0xb9, 0x70, 0xba, 0xe3, 0x02, 0xcf, 0x39, 0x11, 0xbe, + 0x5e, 0x80, 0x93, 0x0a, 0x87, 0x3e, 0xa2, 0xf8, 0x1f, 0xb1, 0xaa, 0x2e, 0xc0, 0xb0, 0xa7, 0xc4, + 0x89, 0x96, 0x29, 0xc7, 0x8b, 0x85, 0x89, 0x31, 0x0e, 0xbd, 0xf2, 0xbc, 0xf8, 0xd2, 0x1e, 0xd5, + 0xe5, 0xec, 0xe2, 0x72, 0x9f, 0x87, 0x62, 0xdb, 0xad, 0x8b, 0x0b, 0xe6, 0xc3, 0x72, 0xb4, 0x6f, + 0x94, 0x17, 0xf7, 0x77, 0x4b, 0x8f, 0xe6, 0xa9, 0x9c, 0xe8, 0xcd, 0x16, 0xce, 0xde, 0x28, 0x2f, + 0x62, 0x5a, 0x19, 0xcd, 0xc1, 0x84, 0xd4, 0xaa, 0xdd, 0xa4, 0x7c, 0xa9, 0xef, 0x89, 0x7b, 0x48, + 0x09, 0xcb, 0xb1, 0x09, 0xc6, 0x49, 0x7c, 0xb4, 0x08, 0x93, 0x5b, 0xed, 0xdb, 0xa4, 0x41, 0x22, + 0xfe, 0xc1, 0x57, 0x09, 0x17, 0x25, 0x0f, 0xc7, 0x4f, 0xd8, 0xab, 0x09, 0x38, 0x4e, 0xd5, 0xb0, + 0xbf, 0xcd, 0xee, 0x03, 0x31, 0x7a, 0x1a, 0x7f, 0xf3, 0x9d, 0x5c, 0xce, 0xbd, 0xac, 0x8a, 0xab, + 0x64, 0x67, 0xcd, 0xa7, 0x7c, 0x48, 0xf6, 0xaa, 0x30, 0xd6, 0x7c, 0x5f, 0xc7, 0x35, 0xff, 0xbb, + 0x05, 0x38, 0xa6, 0x46, 0xc0, 0xe0, 0x96, 0xbf, 0xdb, 0xc7, 0xe0, 0x22, 0x8c, 0xd4, 0xc9, 0xba, + 0xd3, 0x6e, 0x44, 0x4a, 0xaf, 0xd1, 0xcf, 0x55, 0x6d, 0x8b, 0x71, 0x31, 0xd6, 0x71, 0x0e, 0x30, + 0x6c, 0xbf, 0x39, 0xc6, 0x2e, 0xe2, 0xc8, 0xa1, 0x6b, 0x5c, 0xed, 0x1a, 0x2b, 0x77, 0xd7, 0x3c, + 0x06, 0xfd, 0x6e, 0x93, 0x32, 0x66, 0x05, 0x93, 0xdf, 0x2a, 0xd3, 0x42, 0xcc, 0x61, 0xe8, 0x09, + 0x18, 0xac, 0xf9, 0xcd, 0xa6, 0xe3, 0xd5, 0xd9, 0x95, 0x37, 0x3c, 0x3f, 0x42, 0x79, 0xb7, 0x05, + 0x5e, 0x84, 0x25, 0x8c, 0x32, 0xdf, 0x4e, 0xb0, 0xc1, 0x85, 0x3d, 0x82, 0xf9, 0x9e, 0x0b, 0x36, + 0x42, 0xcc, 0x4a, 0xe9, 0x5b, 0xf5, 0x8e, 0x1f, 0x6c, 0xb9, 0xde, 0xc6, 0xa2, 0x1b, 0x88, 0x2d, + 0xa1, 0xee, 0xc2, 0x5b, 0x0a, 0x82, 0x35, 0x2c, 0xb4, 0x0c, 0xfd, 0x2d, 0x3f, 0x88, 0xc2, 0xe9, + 0x01, 0x36, 0xdc, 0x8f, 0xe6, 0x1c, 0x44, 0xfc, 0x6b, 0x2b, 0x7e, 0x10, 0xc5, 0x1f, 0x40, 0xff, + 0x85, 0x98, 0x57, 0x47, 0xd7, 0x60, 0x90, 0x78, 0xdb, 0xcb, 0x81, 0xdf, 0x9c, 0x3e, 0x92, 0x4f, + 0x69, 0x89, 0xa3, 0xf0, 0x65, 0x16, 0xf3, 0xa8, 0xa2, 0x18, 0x4b, 0x12, 0xe8, 0xa3, 0x50, 0x24, + 0xde, 0xf6, 0xf4, 0x20, 0xa3, 0x34, 0x93, 0x43, 0xe9, 0xa6, 0x13, 0xc4, 0x67, 0xfe, 0x92, 0xb7, + 0x8d, 0x69, 0x1d, 0xf4, 0x09, 0x18, 0x96, 0x07, 0x46, 0x28, 0xa4, 0xa8, 0x99, 0x0b, 0x56, 0x1e, + 0x33, 0x98, 0xbc, 0xdb, 0x76, 0x03, 0xd2, 0x24, 0x5e, 0x14, 0xc6, 0x27, 0xa4, 0x84, 0x86, 0x38, + 0xa6, 0x86, 0x6a, 0x30, 0x1a, 0x90, 0xd0, 0xbd, 0x47, 0x2a, 0x7e, 0xc3, 0xad, 0xed, 0x4c, 0x9f, + 0x60, 0xdd, 0x7b, 0xaa, 0xe3, 0x90, 0x61, 0xad, 0x42, 0x2c, 0xe5, 0xd7, 0x4b, 0xb1, 0x41, 0x14, + 0xbd, 0x05, 0x63, 0x01, 0x09, 0x23, 0x27, 0x88, 0x44, 0x2b, 0xd3, 0x4a, 0x2b, 0x37, 0x86, 0x75, + 0x00, 0x7f, 0x4e, 0xc4, 0xcd, 0xc4, 0x10, 0x6c, 0x52, 0x40, 0x9f, 0x90, 0x2a, 0x87, 0x15, 0xbf, + 0xed, 0x45, 0xe1, 0xf4, 0x30, 0xeb, 0x77, 0xa6, 0x6e, 0xfa, 0x66, 0x8c, 0x97, 0xd4, 0x49, 0xf0, + 0xca, 0xd8, 0x20, 0x85, 0x3e, 0x05, 0x63, 0xfc, 0x3f, 0x57, 0xa9, 0x86, 0xd3, 0xc7, 0x18, 0xed, + 0xb3, 0xf9, 0xb4, 0x39, 0xe2, 0xfc, 0x31, 0x41, 0x7c, 0x4c, 0x2f, 0x0d, 0xb1, 0x49, 0x0d, 0x61, + 0x18, 0x6b, 0xb8, 0xdb, 0xc4, 0x23, 0x61, 0x58, 0x09, 0xfc, 0xdb, 0x44, 0x48, 0x88, 0x4f, 0x66, + 0xab, 0x60, 0xfd, 0xdb, 0x44, 0x3c, 0x02, 0xf5, 0x3a, 0xd8, 0x24, 0x81, 0x6e, 0xc0, 0x38, 0x7d, + 0x92, 0xbb, 0x31, 0xd1, 0x91, 0x6e, 0x44, 0xd9, 0xc3, 0x19, 0x1b, 0x95, 0x70, 0x82, 0x08, 0xba, + 0x0e, 0xa3, 0x6c, 0xcc, 0xdb, 0x2d, 0x4e, 0xf4, 0x78, 0x37, 0xa2, 0xcc, 0xa0, 0xa0, 0xaa, 0x55, + 0xc1, 0x06, 0x01, 0xf4, 0x26, 0x0c, 0x37, 0xdc, 0x75, 0x52, 0xdb, 0xa9, 0x35, 0xc8, 0xf4, 0x28, + 0xa3, 0x96, 0x79, 0x18, 0x5e, 0x93, 0x48, 0x9c, 0x3f, 0x57, 0x7f, 0x71, 0x5c, 0x1d, 0xdd, 0x84, + 0xe3, 0x11, 0x09, 0x9a, 0xae, 0xe7, 0xd0, 0x43, 0x4c, 0x3c, 0x09, 0x99, 0x66, 0x7c, 0x8c, 0xad, + 0xae, 0x33, 0x62, 0x36, 0x8e, 0xaf, 0x65, 0x62, 0xe1, 0x9c, 0xda, 0xe8, 0x2e, 0x4c, 0x67, 0x40, + 0xf8, 0xba, 0x3d, 0xca, 0x28, 0xbf, 0x26, 0x28, 0x4f, 0xaf, 0xe5, 0xe0, 0xed, 0x77, 0x80, 0xe1, + 0x5c, 0xea, 0xe8, 0x3a, 0x4c, 0xb0, 0x93, 0xb3, 0xd2, 0x6e, 0x34, 0x44, 0x83, 0xe3, 0xac, 0xc1, + 0x27, 0x24, 0x1f, 0x51, 0x36, 0xc1, 0xfb, 0xbb, 0x25, 0x88, 0xff, 0xe1, 0x64, 0x6d, 0x74, 0x9b, + 0x29, 0x61, 0xdb, 0x81, 0x1b, 0xed, 0xd0, 0x5d, 0x45, 0xee, 0x46, 0xd3, 0x13, 0x1d, 0x05, 0x52, + 0x3a, 0xaa, 0xd2, 0xd4, 0xea, 0x85, 0x38, 0x49, 0x90, 0x5e, 0x05, 0x61, 0x54, 0x77, 0xbd, 0xe9, + 0x49, 0xfe, 0x9e, 0x92, 0x27, 0x69, 0x95, 0x16, 0x62, 0x0e, 0x63, 0x0a, 0x58, 0xfa, 0xe3, 0x3a, + 0xbd, 0x71, 0xa7, 0x18, 0x62, 0xac, 0x80, 0x95, 0x00, 0x1c, 0xe3, 0x50, 0x26, 0x38, 0x8a, 0x76, + 0xa6, 0x11, 0x43, 0x55, 0x07, 0xe2, 0xda, 0xda, 0x27, 0x30, 0x2d, 0xb7, 0x6f, 0xc3, 0xb8, 0x3a, + 0x26, 0xd8, 0x98, 0xa0, 0x12, 0xf4, 0x33, 0xb6, 0x4f, 0x88, 0x4f, 0x87, 0x69, 0x17, 0x18, 0x4b, + 0x88, 0x79, 0x39, 0xeb, 0x82, 0x7b, 0x8f, 0xcc, 0xef, 0x44, 0x84, 0xcb, 0x22, 0x8a, 0x5a, 0x17, + 0x24, 0x00, 0xc7, 0x38, 0xf6, 0xbf, 0xe7, 0xec, 0x73, 0x7c, 0x4b, 0xf4, 0x70, 0x2f, 0x3e, 0x0b, + 0x43, 0xcc, 0xf0, 0xc3, 0x0f, 0xb8, 0x76, 0xb6, 0x3f, 0x66, 0x98, 0xaf, 0x88, 0x72, 0xac, 0x30, + 0xd0, 0xab, 0x30, 0x56, 0xd3, 0x1b, 0x10, 0x97, 0xba, 0x3a, 0x46, 0x8c, 0xd6, 0xb1, 0x89, 0x8b, + 0x2e, 0xc1, 0x10, 0xb3, 0x71, 0xaa, 0xf9, 0x0d, 0xc1, 0x6d, 0x4a, 0xce, 0x64, 0xa8, 0x22, 0xca, + 0xf7, 0xb5, 0xdf, 0x58, 0x61, 0xa3, 0x73, 0x30, 0x40, 0xbb, 0x50, 0xae, 0x88, 0xeb, 0x54, 0x49, + 0x02, 0xaf, 0xb0, 0x52, 0x2c, 0xa0, 0xf6, 0x1f, 0x5b, 0x8c, 0x97, 0x4a, 0x9f, 0xf9, 0xe8, 0x0a, + 0xbb, 0x34, 0xd8, 0x0d, 0xa2, 0x69, 0xe1, 0x1f, 0xd7, 0x6e, 0x02, 0x05, 0xdb, 0x4f, 0xfc, 0xc7, + 0x46, 0x4d, 0xf4, 0x76, 0xf2, 0x66, 0xe0, 0x0c, 0xc5, 0x8b, 0x72, 0x08, 0x92, 0xb7, 0xc3, 0x23, + 0xf1, 0x15, 0x47, 0xfb, 0xd3, 0xe9, 0x8a, 0xb0, 0x7f, 0xaa, 0xa0, 0xad, 0x92, 0x6a, 0xe4, 0x44, + 0x04, 0x55, 0x60, 0xf0, 0x8e, 0xe3, 0x46, 0xae, 0xb7, 0x21, 0xf8, 0xbe, 0xce, 0x17, 0x1d, 0xab, + 0x74, 0x8b, 0x57, 0xe0, 0xdc, 0x8b, 0xf8, 0x83, 0x25, 0x19, 0x4a, 0x31, 0x68, 0x7b, 0x1e, 0xa5, + 0x58, 0xe8, 0x95, 0x22, 0xe6, 0x15, 0x38, 0x45, 0xf1, 0x07, 0x4b, 0x32, 0xe8, 0x1d, 0x00, 0x79, + 0x42, 0x90, 0xba, 0x90, 0x1d, 0x3e, 0xdb, 0x9d, 0xe8, 0x9a, 0xaa, 0xc3, 0x85, 0x93, 0xf1, 0x7f, + 0xac, 0xd1, 0xb3, 0x23, 0x6d, 0x4e, 0xf5, 0xce, 0xa0, 0x4f, 0xd2, 0x2d, 0xea, 0x04, 0x11, 0xa9, + 0xcf, 0x45, 0x62, 0x70, 0x9e, 0xee, 0xed, 0x71, 0xb8, 0xe6, 0x36, 0x89, 0xbe, 0x9d, 0x05, 0x11, + 0x1c, 0xd3, 0xb3, 0x7f, 0xbf, 0x08, 0xd3, 0x79, 0xdd, 0xa5, 0x9b, 0x86, 0xdc, 0x75, 0xa3, 0x05, + 0xca, 0xd6, 0x5a, 0xe6, 0xa6, 0x59, 0x12, 0xe5, 0x58, 0x61, 0xd0, 0xd5, 0x1b, 0xba, 0x1b, 0xf2, + 0x6d, 0xdf, 0x1f, 0xaf, 0xde, 0x2a, 0x2b, 0xc5, 0x02, 0x4a, 0xf1, 0x02, 0xe2, 0x84, 0xc2, 0xf8, + 0x4e, 0x5b, 0xe5, 0x98, 0x95, 0x62, 0x01, 0xd5, 0xa5, 0x8c, 0x7d, 0x5d, 0xa4, 0x8c, 0xc6, 0x10, + 0xf5, 0x3f, 0xd8, 0x21, 0x42, 0x9f, 0x06, 0x58, 0x77, 0x3d, 0x37, 0xdc, 0x64, 0xd4, 0x07, 0x0e, + 0x4c, 0x5d, 0x31, 0xc5, 0xcb, 0x8a, 0x0a, 0xd6, 0x28, 0xa2, 0x97, 0x60, 0x44, 0x1d, 0x20, 0xe5, + 0x45, 0xa6, 0xfa, 0xd7, 0x4c, 0xa9, 0xe2, 0xd3, 0x74, 0x11, 0xeb, 0x78, 0xf6, 0x67, 0x93, 0xeb, + 0x45, 0xec, 0x00, 0x6d, 0x7c, 0xad, 0x5e, 0xc7, 0xb7, 0xd0, 0x79, 0x7c, 0xed, 0xbf, 0x1e, 0x86, + 0x09, 0xa3, 0xb1, 0x76, 0xd8, 0xc3, 0x99, 0x7b, 0x99, 0x5e, 0x40, 0x4e, 0x44, 0xc4, 0xfe, 0xb3, + 0xbb, 0x6f, 0x15, 0xfd, 0x92, 0xa2, 0x3b, 0x80, 0xd7, 0x47, 0x9f, 0x86, 0xe1, 0x86, 0x13, 0x32, + 0x89, 0x25, 0x11, 0xfb, 0xae, 0x17, 0x62, 0xf1, 0x83, 0xd0, 0x09, 0x23, 0xed, 0xd6, 0xe7, 0xb4, + 0x63, 0x92, 0xf4, 0xa6, 0xa4, 0xfc, 0x95, 0xb4, 0xee, 0x54, 0x9d, 0xa0, 0x4c, 0xd8, 0x0e, 0xe6, + 0x30, 0x74, 0x89, 0x1d, 0xad, 0x74, 0x55, 0x2c, 0x50, 0x6e, 0x94, 0x2d, 0xb3, 0x7e, 0x83, 0xc9, + 0x56, 0x30, 0x6c, 0x60, 0xc6, 0x6f, 0xb2, 0x81, 0x0e, 0x6f, 0xb2, 0xa7, 0x60, 0x90, 0xfd, 0x50, + 0x2b, 0x40, 0xcd, 0x46, 0x99, 0x17, 0x63, 0x09, 0x4f, 0x2e, 0x98, 0xa1, 0xde, 0x16, 0x0c, 0x7d, + 0xf5, 0x89, 0x45, 0xcd, 0xcc, 0x2e, 0x86, 0xf8, 0x29, 0x27, 0x96, 0x3c, 0x96, 0x30, 0xf4, 0x6b, + 0x16, 0x20, 0xa7, 0x41, 0x5f, 0xcb, 0xb4, 0x58, 0x3d, 0x6e, 0x80, 0xb1, 0xda, 0xaf, 0x76, 0x1d, + 0xf6, 0x76, 0x38, 0x3b, 0x97, 0xaa, 0xcd, 0x25, 0xa5, 0xaf, 0x88, 0x2e, 0xa2, 0x34, 0x82, 0x7e, + 0x19, 0x5d, 0x73, 0xc3, 0xe8, 0xf3, 0x7f, 0x9f, 0xb8, 0x9c, 0x32, 0xba, 0x84, 0x6e, 0xe8, 0x8f, + 0xaf, 0x91, 0x03, 0x3e, 0xbe, 0xc6, 0x72, 0x1f, 0x5e, 0xdf, 0x9f, 0x78, 0xc0, 0x8c, 0xb2, 0x2f, + 0x7f, 0xa2, 0xcb, 0x03, 0x46, 0x88, 0xd3, 0x7b, 0x79, 0xc6, 0x54, 0x84, 0x1e, 0x78, 0x8c, 0x75, + 0xb9, 0xf3, 0x23, 0xf8, 0x46, 0x48, 0x82, 0xf9, 0x93, 0x52, 0x4d, 0xbc, 0xaf, 0xf3, 0x1e, 0x9a, + 0xde, 0xf8, 0x87, 0x2c, 0x98, 0x4e, 0x0f, 0x10, 0xef, 0xd2, 0xf4, 0x38, 0xeb, 0xbf, 0xdd, 0x69, + 0x64, 0x44, 0xe7, 0xa5, 0xb9, 0xeb, 0xf4, 0x5c, 0x0e, 0x2d, 0x9c, 0xdb, 0x0a, 0xba, 0x04, 0x10, + 0x46, 0x7e, 0x8b, 0x9f, 0xf5, 0x8c, 0x99, 0x1d, 0x66, 0x06, 0x17, 0x50, 0x55, 0xa5, 0xfb, 0xf1, + 0x5d, 0xa0, 0xe1, 0xce, 0xb4, 0xe1, 0x44, 0xce, 0x8a, 0xc9, 0x90, 0x77, 0x2f, 0xea, 0xf2, 0xee, + 0x2e, 0x52, 0xd2, 0x59, 0x39, 0xa7, 0xb3, 0x6f, 0xb5, 0x1d, 0x2f, 0x72, 0xa3, 0x1d, 0x5d, 0x3e, + 0xee, 0x81, 0x39, 0x94, 0xe8, 0x53, 0xd0, 0xdf, 0x70, 0xbd, 0xf6, 0x5d, 0x71, 0xc7, 0x9e, 0xcb, + 0x7e, 0xfe, 0x78, 0xed, 0xbb, 0xe6, 0xe4, 0x94, 0xe8, 0x56, 0x66, 0xe5, 0xfb, 0xbb, 0x25, 0x94, + 0x46, 0xc0, 0x9c, 0xaa, 0xfd, 0x34, 0x8c, 0x2f, 0x3a, 0xa4, 0xe9, 0x7b, 0x4b, 0x5e, 0xbd, 0xe5, + 0xbb, 0x5e, 0x84, 0xa6, 0xa1, 0x8f, 0x31, 0x97, 0xfc, 0x6a, 0xed, 0xa3, 0x83, 0x8f, 0x59, 0x89, + 0xbd, 0x01, 0xc7, 0x16, 0xfd, 0x3b, 0xde, 0x1d, 0x27, 0xa8, 0xcf, 0x55, 0xca, 0x9a, 0xbc, 0x70, + 0x55, 0xca, 0xab, 0xac, 0x7c, 0x69, 0x80, 0x56, 0x93, 0x2f, 0xc2, 0x65, 0xb7, 0x41, 0x72, 0xa4, + 0xba, 0x3f, 0x5b, 0x30, 0x5a, 0x8a, 0xf1, 0x95, 0x4e, 0xd2, 0xca, 0x35, 0x67, 0x78, 0x0b, 0x86, + 0xd6, 0x5d, 0xd2, 0xa8, 0x63, 0xb2, 0x2e, 0x66, 0xe3, 0xc9, 0x7c, 0x83, 0xc7, 0x65, 0x8a, 0xa9, + 0x94, 0xa7, 0x4c, 0xda, 0xb5, 0x2c, 0x2a, 0x63, 0x45, 0x06, 0x6d, 0xc1, 0xa4, 0x9c, 0x33, 0x09, + 0x15, 0xe7, 0xfd, 0x53, 0x9d, 0x96, 0xaf, 0x49, 0x9c, 0x19, 0x7f, 0xe3, 0x04, 0x19, 0x9c, 0x22, + 0x8c, 0x4e, 0x41, 0x5f, 0x93, 0x72, 0x36, 0x7d, 0x6c, 0xf8, 0x99, 0x78, 0x8b, 0x49, 0xea, 0x58, + 0xa9, 0xfd, 0xf3, 0x16, 0x9c, 0x48, 0x8d, 0x8c, 0x90, 0x58, 0x3e, 0xe0, 0x59, 0x48, 0x4a, 0x10, + 0x0b, 0xdd, 0x25, 0x88, 0xf6, 0x7f, 0x61, 0xc1, 0xd1, 0xa5, 0x66, 0x2b, 0xda, 0x59, 0x74, 0x4d, + 0xdb, 0x83, 0x97, 0x61, 0xa0, 0x49, 0xea, 0x6e, 0xbb, 0x29, 0x66, 0xae, 0x24, 0x6f, 0xff, 0x15, + 0x56, 0x4a, 0x4f, 0x90, 0x6a, 0xe4, 0x07, 0xce, 0x06, 0xe1, 0x05, 0x58, 0xa0, 0x33, 0x1e, 0xca, + 0xbd, 0x47, 0xae, 0xb9, 0x4d, 0x37, 0xba, 0xbf, 0xdd, 0x25, 0xcc, 0x06, 0x24, 0x11, 0x1c, 0xd3, + 0xb3, 0xbf, 0x69, 0xc1, 0x84, 0x5c, 0xf7, 0x73, 0xf5, 0x7a, 0x40, 0xc2, 0x10, 0xcd, 0x40, 0xc1, + 0x6d, 0x89, 0x5e, 0x82, 0xe8, 0x65, 0xa1, 0x5c, 0xc1, 0x05, 0xb7, 0x25, 0x9f, 0x6b, 0x8c, 0xc1, + 0x28, 0x9a, 0x16, 0x14, 0x57, 0x44, 0x39, 0x56, 0x18, 0xe8, 0x3c, 0x0c, 0x79, 0x7e, 0x9d, 0xbf, + 0x78, 0x84, 0x0e, 0x9d, 0x62, 0xae, 0x8a, 0x32, 0xac, 0xa0, 0xa8, 0x02, 0xc3, 0xdc, 0xbe, 0x36, + 0x5e, 0xb4, 0x3d, 0x59, 0xe9, 0xb2, 0x2f, 0x5b, 0x93, 0x35, 0x71, 0x4c, 0xc4, 0xfe, 0x53, 0x0b, + 0x46, 0xe5, 0x97, 0xf5, 0xf8, 0x16, 0xa5, 0x5b, 0x2b, 0x7e, 0x87, 0xc6, 0x5b, 0x8b, 0xbe, 0x25, + 0x19, 0xc4, 0x78, 0x42, 0x16, 0x0f, 0xf4, 0x84, 0xbc, 0x08, 0x23, 0x4e, 0xab, 0x55, 0x31, 0xdf, + 0x9f, 0x6c, 0x29, 0xcd, 0xc5, 0xc5, 0x58, 0xc7, 0xb1, 0x7f, 0xae, 0x00, 0xe3, 0xf2, 0x0b, 0xaa, + 0xed, 0xdb, 0x21, 0x89, 0xd0, 0x1a, 0x0c, 0x3b, 0x7c, 0x96, 0x88, 0x5c, 0xe4, 0x8f, 0x65, 0xcb, + 0x45, 0x8d, 0x29, 0x8d, 0x19, 0xe9, 0x39, 0x59, 0x1b, 0xc7, 0x84, 0x50, 0x03, 0xa6, 0x3c, 0x3f, + 0x62, 0x4c, 0x95, 0x82, 0x77, 0x52, 0x55, 0x27, 0xa9, 0x9f, 0x14, 0xd4, 0xa7, 0x56, 0x93, 0x54, + 0x70, 0x9a, 0x30, 0x5a, 0x92, 0xb2, 0xe6, 0x62, 0xbe, 0x90, 0x50, 0x9f, 0xb8, 0x6c, 0x51, 0xb3, + 0xfd, 0x47, 0x16, 0x0c, 0x4b, 0xb4, 0xc3, 0xb0, 0x4a, 0x58, 0x81, 0xc1, 0x90, 0x4d, 0x82, 0x1c, + 0x1a, 0xbb, 0x53, 0xc7, 0xf9, 0x7c, 0xc5, 0xbc, 0x22, 0xff, 0x1f, 0x62, 0x49, 0x83, 0xa9, 0x1a, + 0x55, 0xf7, 0xdf, 0x27, 0xaa, 0x46, 0xd5, 0x9f, 0x9c, 0x4b, 0xe9, 0x1f, 0x58, 0x9f, 0x35, 0xd9, + 0x3d, 0x7d, 0xd2, 0xb4, 0x02, 0xb2, 0xee, 0xde, 0x4d, 0x3e, 0x69, 0x2a, 0xac, 0x14, 0x0b, 0x28, + 0x7a, 0x07, 0x46, 0x6b, 0x52, 0xc7, 0x14, 0xef, 0xf0, 0x73, 0x1d, 0xf5, 0x9d, 0x4a, 0x35, 0xce, + 0x65, 0xa4, 0x0b, 0x5a, 0x7d, 0x6c, 0x50, 0x33, 0xed, 0xc7, 0x8a, 0xdd, 0xec, 0xc7, 0x62, 0xba, + 0xf9, 0xd6, 0x54, 0xbf, 0x60, 0xc1, 0x00, 0xd7, 0x2d, 0xf4, 0xa6, 0xda, 0xd1, 0x2c, 0x05, 0xe2, + 0xb1, 0xbb, 0x49, 0x0b, 0x05, 0x67, 0x83, 0x56, 0x60, 0x98, 0xfd, 0x60, 0xba, 0x91, 0x62, 0xbe, + 0xb7, 0x19, 0x6f, 0x55, 0xef, 0xe0, 0x4d, 0x59, 0x0d, 0xc7, 0x14, 0xec, 0x9f, 0x2e, 0xd2, 0xd3, + 0x2d, 0x46, 0x35, 0x2e, 0x7d, 0xeb, 0xe1, 0x5d, 0xfa, 0x85, 0x87, 0x75, 0xe9, 0x6f, 0xc0, 0x44, + 0x4d, 0xb3, 0x2b, 0x88, 0x67, 0xf2, 0x7c, 0xc7, 0x45, 0xa2, 0x99, 0x20, 0x70, 0xe9, 0xeb, 0x82, + 0x49, 0x04, 0x27, 0xa9, 0xa2, 0x4f, 0xc2, 0x28, 0x9f, 0x67, 0xd1, 0x0a, 0x37, 0xc1, 0x7b, 0x22, + 0x7f, 0xbd, 0xe8, 0x4d, 0x70, 0x69, 0xbd, 0x56, 0x1d, 0x1b, 0xc4, 0xec, 0x7f, 0xb1, 0x00, 0x2d, + 0xb5, 0x36, 0x49, 0x93, 0x04, 0x4e, 0x23, 0x56, 0x0f, 0x7e, 0xc9, 0x82, 0x69, 0x92, 0x2a, 0x5e, + 0xf0, 0x9b, 0x4d, 0x21, 0x0c, 0xc8, 0x91, 0x57, 0x2d, 0xe5, 0xd4, 0x89, 0x1f, 0x04, 0x79, 0x18, + 0x38, 0xb7, 0x3d, 0xb4, 0x02, 0x47, 0xf8, 0x2d, 0xa9, 0x00, 0x9a, 0x95, 0xde, 0x23, 0x82, 0xf0, + 0x91, 0xb5, 0x34, 0x0a, 0xce, 0xaa, 0x67, 0xff, 0xd1, 0x18, 0xe4, 0xf6, 0xe2, 0x03, 0xbd, 0xe8, + 0x07, 0x7a, 0xd1, 0x0f, 0xf4, 0xa2, 0x1f, 0xe8, 0x45, 0x3f, 0xd0, 0x8b, 0x7e, 0xa0, 0x17, 0x7d, + 0x9f, 0xea, 0x45, 0x7f, 0xc6, 0x82, 0x63, 0xea, 0xfa, 0x32, 0x1e, 0xec, 0x9f, 0x83, 0x23, 0x7c, + 0xbb, 0x2d, 0x34, 0x1c, 0xb7, 0xb9, 0x46, 0x9a, 0xad, 0x86, 0x13, 0x49, 0xeb, 0xa7, 0x8b, 0x99, + 0x2b, 0x37, 0xe1, 0x62, 0x61, 0x54, 0xe4, 0xbe, 0x6a, 0x19, 0x00, 0x9c, 0xd5, 0x8c, 0xfd, 0xfb, + 0x43, 0xd0, 0xbf, 0xb4, 0x4d, 0xbc, 0xe8, 0x10, 0x9e, 0x36, 0x35, 0x18, 0x77, 0xbd, 0x6d, 0xbf, + 0xb1, 0x4d, 0xea, 0x1c, 0x7e, 0x90, 0x17, 0xf8, 0x71, 0x41, 0x7a, 0xbc, 0x6c, 0x90, 0xc0, 0x09, + 0x92, 0x0f, 0x43, 0xbb, 0x74, 0x19, 0x06, 0xf8, 0xe5, 0x23, 0x54, 0x4b, 0x99, 0x67, 0x36, 0x1b, + 0x44, 0x71, 0xa5, 0xc6, 0x9a, 0x2f, 0x7e, 0xb9, 0x89, 0xea, 0xe8, 0xb3, 0x30, 0xbe, 0xee, 0x06, + 0x61, 0xb4, 0xe6, 0x36, 0xe9, 0xd5, 0xd0, 0x6c, 0xdd, 0x87, 0x36, 0x49, 0x8d, 0xc3, 0xb2, 0x41, + 0x09, 0x27, 0x28, 0xa3, 0x0d, 0x18, 0x6b, 0x38, 0x7a, 0x53, 0x83, 0x07, 0x6e, 0x4a, 0xdd, 0x0e, + 0xd7, 0x74, 0x42, 0xd8, 0xa4, 0x4b, 0xb7, 0x53, 0x8d, 0x29, 0x44, 0x86, 0x98, 0x38, 0x43, 0x6d, + 0x27, 0xae, 0x09, 0xe1, 0x30, 0xca, 0xa0, 0x31, 0x47, 0x85, 0x61, 0x93, 0x41, 0xd3, 0xdc, 0x11, + 0x3e, 0x03, 0xc3, 0x84, 0x0e, 0x21, 0x25, 0x2c, 0x2e, 0x98, 0x0b, 0xbd, 0xf5, 0x75, 0xc5, 0xad, + 0x05, 0xbe, 0xa9, 0xc7, 0x5b, 0x92, 0x94, 0x70, 0x4c, 0x14, 0x2d, 0xc0, 0x40, 0x48, 0x02, 0x57, + 0xe9, 0x0a, 0x3a, 0x4c, 0x23, 0x43, 0xe3, 0xce, 0x90, 0xfc, 0x37, 0x16, 0x55, 0xe9, 0xf2, 0x72, + 0x98, 0x28, 0x96, 0x5d, 0x06, 0xda, 0xf2, 0x9a, 0x63, 0xa5, 0x58, 0x40, 0xd1, 0x9b, 0x30, 0x18, + 0x90, 0x06, 0x53, 0x14, 0x8f, 0xf5, 0xbe, 0xc8, 0xb9, 0xde, 0x99, 0xd7, 0xc3, 0x92, 0x00, 0xba, + 0x0a, 0x28, 0x20, 0x94, 0xc1, 0x73, 0xbd, 0x0d, 0x65, 0xbe, 0x2f, 0x0e, 0x5a, 0xc5, 0x48, 0xe3, + 0x18, 0x43, 0xfa, 0xc1, 0xe2, 0x8c, 0x6a, 0xe8, 0x32, 0x4c, 0xa9, 0xd2, 0xb2, 0x17, 0x46, 0x0e, + 0x3d, 0xe0, 0xb8, 0xb8, 0x5e, 0xc9, 0x57, 0x70, 0x12, 0x01, 0xa7, 0xeb, 0xd8, 0xbf, 0x61, 0x01, + 0x1f, 0xe7, 0x43, 0x90, 0x2a, 0xbc, 0x6e, 0x4a, 0x15, 0x4e, 0xe6, 0xce, 0x5c, 0x8e, 0x44, 0xe1, + 0x37, 0x2c, 0x18, 0xd1, 0x66, 0x36, 0x5e, 0xb3, 0x56, 0x87, 0x35, 0xdb, 0x86, 0x49, 0xba, 0xd2, + 0xaf, 0xdf, 0x0e, 0x49, 0xb0, 0x4d, 0xea, 0x6c, 0x61, 0x16, 0xee, 0x6f, 0x61, 0x2a, 0x53, 0xe1, + 0x6b, 0x09, 0x82, 0x38, 0xd5, 0x84, 0xfd, 0x19, 0xd9, 0x55, 0x65, 0x59, 0x5d, 0x53, 0x73, 0x9e, + 0xb0, 0xac, 0x56, 0xb3, 0x8a, 0x63, 0x1c, 0xba, 0xd5, 0x36, 0xfd, 0x30, 0x4a, 0x5a, 0x56, 0x5f, + 0xf1, 0xc3, 0x08, 0x33, 0x88, 0xfd, 0x02, 0xc0, 0xd2, 0x5d, 0x52, 0xe3, 0x2b, 0x56, 0x7f, 0xf4, + 0x58, 0xf9, 0x8f, 0x1e, 0xfb, 0x6f, 0x2c, 0x18, 0x5f, 0x5e, 0x30, 0x6e, 0xae, 0x59, 0x00, 0xfe, + 0x52, 0xbb, 0x75, 0x6b, 0x55, 0x9a, 0xf7, 0x70, 0x0b, 0x07, 0x55, 0x8a, 0x35, 0x0c, 0x74, 0x12, + 0x8a, 0x8d, 0xb6, 0x27, 0xc4, 0x9e, 0x83, 0xf4, 0x7a, 0xbc, 0xd6, 0xf6, 0x30, 0x2d, 0xd3, 0x7c, + 0xe0, 0x8a, 0x3d, 0xfb, 0xc0, 0x75, 0x0d, 0xc5, 0x83, 0x4a, 0xd0, 0x7f, 0xe7, 0x8e, 0x5b, 0xe7, + 0x11, 0x06, 0x84, 0xe9, 0xd1, 0xad, 0x5b, 0xe5, 0xc5, 0x10, 0xf3, 0x72, 0xfb, 0xcb, 0x45, 0x98, + 0x59, 0x6e, 0x90, 0xbb, 0xef, 0x31, 0xca, 0x42, 0xaf, 0x1e, 0x7c, 0x07, 0x13, 0x20, 0x1d, 0xd4, + 0x4b, 0xb3, 0xfb, 0x78, 0xac, 0xc3, 0x20, 0x37, 0x2c, 0x96, 0x31, 0x17, 0x32, 0xd5, 0xb9, 0xf9, + 0x03, 0x32, 0xcb, 0x0d, 0x94, 0x85, 0x3a, 0x57, 0x5d, 0x98, 0xa2, 0x14, 0x4b, 0xe2, 0x33, 0xaf, + 0xc0, 0xa8, 0x8e, 0x79, 0x20, 0x7f, 0xe9, 0x1f, 0x2e, 0xc2, 0x24, 0xed, 0xc1, 0x43, 0x9d, 0x88, + 0x1b, 0xe9, 0x89, 0x78, 0xd0, 0x3e, 0xb3, 0xdd, 0x67, 0xe3, 0x9d, 0xe4, 0x6c, 0x5c, 0xcc, 0x9b, + 0x8d, 0xc3, 0x9e, 0x83, 0x1f, 0xb1, 0xe0, 0xc8, 0x72, 0xc3, 0xaf, 0x6d, 0x25, 0xfc, 0x5a, 0x5f, + 0x82, 0x11, 0x7a, 0x1c, 0x87, 0x46, 0x88, 0x17, 0x23, 0xe8, 0x8f, 0x00, 0x61, 0x1d, 0x4f, 0xab, + 0x76, 0xe3, 0x46, 0x79, 0x31, 0x2b, 0x56, 0x90, 0x00, 0x61, 0x1d, 0xcf, 0xfe, 0x4b, 0x0b, 0x4e, + 0x5f, 0x5e, 0x58, 0x8a, 0x97, 0x62, 0x2a, 0x5c, 0xd1, 0x39, 0x18, 0x68, 0xd5, 0xb5, 0xae, 0xc4, + 0x62, 0xe1, 0x45, 0xd6, 0x0b, 0x01, 0x7d, 0xbf, 0x44, 0x06, 0xbb, 0x01, 0x70, 0x19, 0x57, 0x16, + 0xc4, 0xb9, 0x2b, 0xb5, 0x40, 0x56, 0xae, 0x16, 0xe8, 0x09, 0x18, 0xa4, 0xf7, 0x82, 0x5b, 0x93, + 0xfd, 0xe6, 0x06, 0x1b, 0xbc, 0x08, 0x4b, 0x98, 0xfd, 0xeb, 0x16, 0x1c, 0xb9, 0xec, 0x46, 0xf4, + 0xd2, 0x4e, 0xc6, 0xe3, 0xa1, 0xb7, 0x76, 0xe8, 0x46, 0x7e, 0xb0, 0x93, 0x8c, 0xc7, 0x83, 0x15, + 0x04, 0x6b, 0x58, 0xfc, 0x83, 0xb6, 0x5d, 0xe6, 0x29, 0x53, 0x30, 0xf5, 0x6e, 0x58, 0x94, 0x63, + 0x85, 0x41, 0xc7, 0xab, 0xee, 0x06, 0x4c, 0x64, 0xb9, 0x23, 0x0e, 0x6e, 0x35, 0x5e, 0x8b, 0x12, + 0x80, 0x63, 0x1c, 0xfb, 0x9f, 0x2c, 0x28, 0x5d, 0xe6, 0xfe, 0xbe, 0xeb, 0x61, 0xce, 0xa1, 0xfb, + 0x02, 0x0c, 0x13, 0xa9, 0x20, 0x10, 0xbd, 0x56, 0x8c, 0xa8, 0xd2, 0x1c, 0xf0, 0xb0, 0x40, 0x0a, + 0xaf, 0x07, 0xe7, 0xfb, 0x83, 0x79, 0x4f, 0x2f, 0x03, 0x22, 0x7a, 0x5b, 0x7a, 0x9c, 0x24, 0x16, + 0x70, 0x65, 0x29, 0x05, 0xc5, 0x19, 0x35, 0xec, 0x9f, 0xb7, 0xe0, 0x98, 0xfa, 0xe0, 0xf7, 0xdd, + 0x67, 0xda, 0xbf, 0x53, 0x80, 0xb1, 0x2b, 0x6b, 0x6b, 0x95, 0xcb, 0x24, 0xd2, 0x56, 0x65, 0x67, + 0xb5, 0x3f, 0xd6, 0xb4, 0x97, 0x9d, 0xde, 0x88, 0xed, 0xc8, 0x6d, 0xcc, 0xf2, 0xe8, 0x7f, 0xb3, + 0x65, 0x2f, 0xba, 0x1e, 0x54, 0xa3, 0xc0, 0xf5, 0x36, 0x32, 0x57, 0xba, 0xe4, 0x59, 0x8a, 0x79, + 0x3c, 0x0b, 0x7a, 0x01, 0x06, 0x58, 0xf8, 0x41, 0x39, 0x09, 0x8f, 0xa8, 0x27, 0x16, 0x2b, 0xdd, + 0xdf, 0x2d, 0x0d, 0xdf, 0xc0, 0x65, 0xfe, 0x07, 0x0b, 0x54, 0x74, 0x03, 0x46, 0x36, 0xa3, 0xa8, + 0x75, 0x85, 0x38, 0x75, 0x12, 0xc8, 0x53, 0xf6, 0x4c, 0xd6, 0x29, 0x4b, 0x07, 0x81, 0xa3, 0xc5, + 0x07, 0x53, 0x5c, 0x16, 0x62, 0x9d, 0x8e, 0x5d, 0x05, 0x88, 0x61, 0x0f, 0x48, 0x71, 0x63, 0xaf, + 0xc1, 0x30, 0xfd, 0xdc, 0xb9, 0x86, 0xeb, 0x74, 0x56, 0x8d, 0x3f, 0x03, 0xc3, 0x52, 0xf1, 0x1d, + 0x8a, 0xe0, 0x20, 0xec, 0x46, 0x92, 0x7a, 0xf1, 0x10, 0xc7, 0x70, 0xfb, 0x71, 0x10, 0xb6, 0xc3, + 0x9d, 0x48, 0xda, 0xeb, 0x70, 0x94, 0x19, 0x41, 0x3b, 0xd1, 0xa6, 0xb1, 0x46, 0xbb, 0x2f, 0x86, + 0x67, 0xc5, 0xbb, 0xae, 0xa0, 0xec, 0x7d, 0xa4, 0xf3, 0xf9, 0xa8, 0xa4, 0x18, 0xbf, 0xf1, 0xec, + 0x7f, 0xec, 0x83, 0x47, 0xca, 0xd5, 0xfc, 0xa8, 0x56, 0x97, 0x60, 0x94, 0xb3, 0x8b, 0x74, 0x69, + 0x38, 0x0d, 0xd1, 0xae, 0x92, 0x80, 0xae, 0x69, 0x30, 0x6c, 0x60, 0xa2, 0xd3, 0x50, 0x74, 0xdf, + 0xf5, 0x92, 0xae, 0x99, 0xe5, 0xb7, 0x56, 0x31, 0x2d, 0xa7, 0x60, 0xca, 0x79, 0xf2, 0x23, 0x5d, + 0x81, 0x15, 0xf7, 0xf9, 0x3a, 0x8c, 0xbb, 0x61, 0x2d, 0x74, 0xcb, 0x1e, 0xdd, 0xa7, 0xda, 0x4e, + 0x57, 0x32, 0x07, 0xda, 0x69, 0x05, 0xc5, 0x09, 0x6c, 0xed, 0x7e, 0xe9, 0xef, 0x99, 0x7b, 0xed, + 0x1a, 0x53, 0x83, 0x1e, 0xff, 0x2d, 0xf6, 0x75, 0x21, 0x13, 0xc1, 0x8b, 0xe3, 0x9f, 0x7f, 0x70, + 0x88, 0x25, 0x8c, 0x3e, 0xe8, 0x6a, 0x9b, 0x4e, 0x6b, 0xae, 0x1d, 0x6d, 0x2e, 0xba, 0x61, 0xcd, + 0xdf, 0x26, 0xc1, 0x0e, 0x7b, 0x8b, 0x0f, 0xc5, 0x0f, 0x3a, 0x05, 0x58, 0xb8, 0x32, 0x57, 0xa1, + 0x98, 0x38, 0x5d, 0x07, 0xcd, 0xc1, 0x84, 0x2c, 0xac, 0x92, 0x90, 0x5d, 0x01, 0x23, 0x8c, 0x8c, + 0x72, 0x96, 0x14, 0xc5, 0x8a, 0x48, 0x12, 0xdf, 0x64, 0x70, 0xe1, 0x41, 0x30, 0xb8, 0x2f, 0xc3, + 0x98, 0xeb, 0xb9, 0x91, 0xeb, 0x44, 0x3e, 0xd7, 0x1f, 0xf1, 0x67, 0x37, 0x13, 0x30, 0x97, 0x75, + 0x00, 0x36, 0xf1, 0xec, 0xff, 0xb3, 0x0f, 0xa6, 0xd8, 0xb4, 0x7d, 0xb0, 0xc2, 0xbe, 0x97, 0x56, + 0xd8, 0x8d, 0xf4, 0x0a, 0x7b, 0x10, 0x9c, 0xfb, 0x7d, 0x2f, 0xb3, 0x2f, 0x58, 0x30, 0xc5, 0x64, + 0xdc, 0xc6, 0x32, 0xbb, 0x00, 0xc3, 0x81, 0xe1, 0xc7, 0x3a, 0xac, 0x2b, 0xb5, 0xa4, 0x4b, 0x6a, + 0x8c, 0x83, 0xde, 0x00, 0x68, 0xc5, 0x32, 0xf4, 0x82, 0x11, 0x7c, 0x14, 0x72, 0xc5, 0xe7, 0x5a, + 0x1d, 0xfb, 0xb3, 0x30, 0xac, 0x1c, 0x55, 0xa5, 0xa7, 0xba, 0x95, 0xe3, 0xa9, 0xde, 0x9d, 0x8d, + 0x90, 0xb6, 0x71, 0xc5, 0x4c, 0xdb, 0xb8, 0xff, 0xcb, 0x82, 0x58, 0xc3, 0x81, 0xde, 0x82, 0xe1, + 0x96, 0xcf, 0x4c, 0xa9, 0x03, 0xe9, 0x9f, 0xf0, 0x78, 0x47, 0x15, 0x09, 0x8f, 0x30, 0x18, 0xf0, + 0xe9, 0xa8, 0xc8, 0xaa, 0x38, 0xa6, 0x82, 0xae, 0xc2, 0x60, 0x2b, 0x20, 0xd5, 0x88, 0x85, 0xbf, + 0xea, 0x9d, 0x20, 0x5f, 0xbe, 0xbc, 0x22, 0x96, 0x14, 0x12, 0x96, 0xa9, 0xc5, 0xde, 0x2d, 0x53, + 0xed, 0xdf, 0x2a, 0xc0, 0x64, 0xb2, 0x11, 0xf4, 0x1a, 0xf4, 0x91, 0xbb, 0xa4, 0x26, 0xbe, 0x34, + 0x93, 0x9b, 0x88, 0xa5, 0x2b, 0x7c, 0xe8, 0xe8, 0x7f, 0xcc, 0x6a, 0xa1, 0x2b, 0x30, 0x48, 0x59, + 0x89, 0xcb, 0x2a, 0x48, 0xe4, 0xa3, 0x79, 0xec, 0x88, 0xe2, 0xc9, 0xf8, 0x67, 0x89, 0x22, 0x2c, + 0xab, 0x33, 0x53, 0xb6, 0x5a, 0xab, 0x4a, 0x5f, 0x69, 0x51, 0x27, 0x61, 0xc2, 0xda, 0x42, 0x85, + 0x23, 0x09, 0x6a, 0xdc, 0x94, 0x4d, 0x16, 0xe2, 0x98, 0x08, 0x7a, 0x03, 0xfa, 0xc3, 0x06, 0x21, + 0x2d, 0x61, 0xab, 0x90, 0x29, 0x1f, 0xad, 0x52, 0x04, 0x41, 0x89, 0xc9, 0x53, 0x58, 0x01, 0xe6, + 0x15, 0xed, 0xdf, 0xb5, 0x00, 0xb8, 0xed, 0x9f, 0xe3, 0x6d, 0x90, 0x43, 0x50, 0x29, 0x2c, 0x42, + 0x5f, 0xd8, 0x22, 0xb5, 0x4e, 0x1e, 0x06, 0x71, 0x7f, 0xaa, 0x2d, 0x52, 0x8b, 0x57, 0x3b, 0xfd, + 0x87, 0x59, 0x6d, 0xfb, 0x47, 0x01, 0xc6, 0x63, 0xb4, 0x72, 0x44, 0x9a, 0xe8, 0x39, 0x23, 0xb2, + 0xce, 0xc9, 0x44, 0x64, 0x9d, 0x61, 0x86, 0xad, 0x49, 0xaf, 0x3f, 0x0b, 0xc5, 0xa6, 0x73, 0x57, + 0x88, 0x27, 0x9f, 0xe9, 0xdc, 0x0d, 0x4a, 0x7f, 0x76, 0xc5, 0xb9, 0xcb, 0x5f, 0xf0, 0xcf, 0xc8, + 0xdd, 0xb9, 0xe2, 0xdc, 0xed, 0x6a, 0x05, 0x4f, 0x1b, 0x61, 0x6d, 0xb9, 0x9e, 0x30, 0x6b, 0xeb, + 0xa9, 0x2d, 0xd7, 0x4b, 0xb6, 0xe5, 0x7a, 0x3d, 0xb4, 0xe5, 0x7a, 0xe8, 0x1e, 0x0c, 0x0a, 0xab, + 0x53, 0x11, 0xf2, 0xef, 0x42, 0x0f, 0xed, 0x09, 0xa3, 0x55, 0xde, 0xe6, 0x05, 0x29, 0xa1, 0x10, + 0xa5, 0x5d, 0xdb, 0x95, 0x0d, 0xa2, 0xff, 0xd4, 0x82, 0x71, 0xf1, 0x1b, 0x93, 0x77, 0xdb, 0x24, + 0x8c, 0x04, 0x07, 0xff, 0x91, 0xde, 0xfb, 0x20, 0x2a, 0xf2, 0xae, 0x7c, 0x44, 0x5e, 0xb6, 0x26, + 0xb0, 0x6b, 0x8f, 0x12, 0xbd, 0x40, 0xbf, 0x65, 0xc1, 0xd1, 0xa6, 0x73, 0x97, 0xb7, 0xc8, 0xcb, + 0xb0, 0x13, 0xb9, 0xbe, 0xb0, 0xde, 0x78, 0xad, 0xb7, 0xe9, 0x4f, 0x55, 0xe7, 0x9d, 0x94, 0xaa, + 0xda, 0xa3, 0x59, 0x28, 0x5d, 0xbb, 0x9a, 0xd9, 0xaf, 0x99, 0x75, 0x18, 0x92, 0xeb, 0xed, 0x61, + 0x9a, 0xd4, 0xb3, 0x76, 0xc4, 0x5a, 0x7b, 0xa8, 0xed, 0x7c, 0x16, 0x46, 0xf5, 0x35, 0xf6, 0x50, + 0xdb, 0x7a, 0x17, 0x8e, 0x64, 0xac, 0xa5, 0x87, 0xda, 0xe4, 0x1d, 0x38, 0x99, 0xbb, 0x3e, 0x1e, + 0xaa, 0x4b, 0xc4, 0xef, 0x58, 0xfa, 0x39, 0x78, 0x08, 0x7a, 0x9d, 0x05, 0x53, 0xaf, 0x73, 0xa6, + 0xf3, 0xce, 0xc9, 0x51, 0xee, 0xbc, 0xa3, 0x77, 0x9a, 0x9e, 0xea, 0xe8, 0x4d, 0x18, 0x68, 0xd0, + 0x12, 0x69, 0xbb, 0x6c, 0x77, 0xdf, 0x91, 0x31, 0x47, 0xcd, 0xca, 0x43, 0x2c, 0x28, 0xd8, 0x5f, + 0xb1, 0x20, 0xc3, 0xa9, 0x83, 0x72, 0x58, 0x6d, 0xb7, 0xce, 0x86, 0xa4, 0x18, 0x73, 0x58, 0x2a, + 0xf0, 0xcc, 0x69, 0x28, 0x6e, 0xb8, 0x75, 0xe1, 0xcd, 0xac, 0xc0, 0x97, 0x29, 0x78, 0xc3, 0xad, + 0xa3, 0x65, 0x40, 0x61, 0xbb, 0xd5, 0x6a, 0x30, 0x83, 0x27, 0xa7, 0x71, 0x39, 0xf0, 0xdb, 0x2d, + 0x6e, 0xa8, 0x5c, 0xe4, 0xe2, 0xa5, 0x6a, 0x0a, 0x8a, 0x33, 0x6a, 0xd8, 0x7f, 0x60, 0x41, 0xdf, + 0x21, 0x4c, 0x13, 0x36, 0xa7, 0xe9, 0xb9, 0x5c, 0xd2, 0x22, 0x53, 0xc4, 0x2c, 0x76, 0xee, 0x2c, + 0xdd, 0x8d, 0x88, 0x17, 0x32, 0x86, 0x23, 0x73, 0xd6, 0x76, 0x2d, 0x38, 0x72, 0xcd, 0x77, 0xea, + 0xf3, 0x4e, 0xc3, 0xf1, 0x6a, 0x24, 0x28, 0x7b, 0x1b, 0x07, 0xf2, 0x0a, 0x28, 0x74, 0xf5, 0x0a, + 0xb8, 0x04, 0x03, 0x6e, 0x4b, 0x0b, 0x35, 0x7f, 0x96, 0xce, 0x6e, 0xb9, 0x22, 0xa2, 0xcc, 0x23, + 0xa3, 0x71, 0x56, 0x8a, 0x05, 0x3e, 0x5d, 0x96, 0xdc, 0x1c, 0xaf, 0x2f, 0x7f, 0x59, 0xd2, 0x57, + 0x52, 0x32, 0x84, 0x9a, 0x61, 0x38, 0xbe, 0x09, 0x46, 0x13, 0xc2, 0x4d, 0x0a, 0xc3, 0xa0, 0xcb, + 0xbf, 0x54, 0xac, 0xcd, 0x27, 0xb3, 0x5f, 0x2f, 0xa9, 0x81, 0xd1, 0xfc, 0x01, 0x79, 0x01, 0x96, + 0x84, 0xec, 0x4b, 0x90, 0x19, 0xf2, 0xa6, 0xbb, 0x64, 0xca, 0xfe, 0x04, 0x4c, 0xb1, 0x9a, 0x07, + 0x94, 0xfa, 0xd8, 0x09, 0x79, 0x7a, 0x46, 0xd4, 0x60, 0xfb, 0x7f, 0xb5, 0x00, 0xad, 0xf8, 0x75, + 0x77, 0x7d, 0x47, 0x10, 0xe7, 0xdf, 0xff, 0x2e, 0x94, 0xf8, 0xb3, 0x3a, 0x19, 0x59, 0x77, 0xa1, + 0xe1, 0x84, 0xa1, 0x26, 0xcb, 0x7f, 0x52, 0xb4, 0x5b, 0x5a, 0xeb, 0x8c, 0x8e, 0xbb, 0xd1, 0x43, + 0x6f, 0x25, 0x02, 0x1d, 0x7e, 0x34, 0x15, 0xe8, 0xf0, 0xc9, 0x4c, 0x8b, 0x9a, 0x74, 0xef, 0x65, + 0x00, 0x44, 0xfb, 0x8b, 0x16, 0x4c, 0xac, 0x26, 0x22, 0xc5, 0x9e, 0x63, 0xe6, 0x05, 0x19, 0x3a, + 0xaa, 0x2a, 0x2b, 0xc5, 0x02, 0xfa, 0xc0, 0x65, 0xb8, 0xdf, 0xb6, 0x20, 0x0e, 0xb1, 0x75, 0x08, + 0x2c, 0xf7, 0x82, 0xc1, 0x72, 0x67, 0x3e, 0x5f, 0x54, 0x77, 0xf2, 0x38, 0x6e, 0x74, 0x55, 0xcd, + 0x49, 0x87, 0x97, 0x4b, 0x4c, 0x86, 0xef, 0xb3, 0x71, 0x73, 0xe2, 0xd4, 0x6c, 0x7c, 0xa3, 0x00, + 0x48, 0xe1, 0xf6, 0x1c, 0x1c, 0x33, 0x5d, 0xe3, 0xc1, 0x04, 0xc7, 0xdc, 0x06, 0xc4, 0x0c, 0x64, + 0x02, 0xc7, 0x0b, 0x39, 0x59, 0x57, 0x48, 0xad, 0x0f, 0x66, 0x7d, 0x33, 0x23, 0xbd, 0x65, 0xaf, + 0xa5, 0xa8, 0xe1, 0x8c, 0x16, 0x34, 0xc3, 0xa7, 0xfe, 0x5e, 0x0d, 0x9f, 0x06, 0xba, 0xb8, 0x7d, + 0x7f, 0xcd, 0x82, 0x31, 0x35, 0x4c, 0xef, 0x13, 0xe7, 0x11, 0xd5, 0x9f, 0x9c, 0x7b, 0xa5, 0xa2, + 0x75, 0x99, 0x31, 0x03, 0xdf, 0xc7, 0xdc, 0xf7, 0x9d, 0x86, 0x7b, 0x8f, 0xa8, 0x18, 0xce, 0x25, + 0xe1, 0x8e, 0x2f, 0x4a, 0xf7, 0x77, 0x4b, 0x63, 0xea, 0x1f, 0x8f, 0x1a, 0x1b, 0x57, 0xb1, 0x7f, + 0x99, 0x6e, 0x76, 0x73, 0x29, 0xa2, 0x97, 0xa0, 0xbf, 0xb5, 0xe9, 0x84, 0x24, 0xe1, 0x64, 0xd7, + 0x5f, 0xa1, 0x85, 0xfb, 0xbb, 0xa5, 0x71, 0x55, 0x81, 0x95, 0x60, 0x8e, 0xdd, 0x7b, 0xc8, 0xd1, + 0xf4, 0xe2, 0xec, 0x1a, 0x72, 0xf4, 0x5f, 0x2c, 0xe8, 0x5b, 0xa5, 0xb7, 0xd7, 0xc3, 0x3f, 0x02, + 0x5e, 0x37, 0x8e, 0x80, 0x53, 0x79, 0xd9, 0x8c, 0x72, 0x77, 0xff, 0x72, 0x62, 0xf7, 0x9f, 0xc9, + 0xa5, 0xd0, 0x79, 0xe3, 0x37, 0x61, 0x84, 0xe5, 0x48, 0x12, 0x0e, 0x85, 0x2f, 0x18, 0x1b, 0xbe, + 0x94, 0xd8, 0xf0, 0x13, 0x1a, 0xaa, 0xb6, 0xd3, 0x9f, 0x82, 0x41, 0xe1, 0xa1, 0x96, 0x8c, 0x82, + 0x20, 0x70, 0xb1, 0x84, 0xdb, 0xbf, 0x50, 0x04, 0x23, 0x27, 0x13, 0xfa, 0x23, 0x0b, 0x66, 0x03, + 0x6e, 0xb9, 0x5e, 0x5f, 0x6c, 0x07, 0xae, 0xb7, 0x51, 0xad, 0x6d, 0x92, 0x7a, 0xbb, 0xe1, 0x7a, + 0x1b, 0xe5, 0x0d, 0xcf, 0x57, 0xc5, 0x4b, 0x77, 0x49, 0xad, 0xcd, 0xb4, 0xca, 0x5d, 0x12, 0x40, + 0x29, 0x0f, 0x90, 0xe7, 0xf7, 0x76, 0x4b, 0xb3, 0xf8, 0x40, 0xb4, 0xf1, 0x01, 0xfb, 0x82, 0xfe, + 0xd2, 0x82, 0x0b, 0x3c, 0x37, 0x50, 0xef, 0xfd, 0xef, 0x20, 0xe1, 0xa8, 0x48, 0x52, 0x31, 0x91, + 0x35, 0x12, 0x34, 0xe7, 0x5f, 0x16, 0x03, 0x7a, 0xa1, 0x72, 0xb0, 0xb6, 0xf0, 0x41, 0x3b, 0x67, + 0xff, 0xb7, 0x45, 0x18, 0x13, 0xa1, 0x29, 0xc5, 0x1d, 0xf0, 0x92, 0xb1, 0x24, 0x1e, 0x4d, 0x2c, + 0x89, 0x29, 0x03, 0xf9, 0xc1, 0x1c, 0xff, 0x21, 0x4c, 0xd1, 0xc3, 0xf9, 0x0a, 0x71, 0x82, 0xe8, + 0x36, 0x71, 0xb8, 0x3d, 0x63, 0xf1, 0xc0, 0xa7, 0xbf, 0x12, 0xac, 0x5f, 0x4b, 0x12, 0xc3, 0x69, + 0xfa, 0xdf, 0x4b, 0x77, 0x8e, 0x07, 0x93, 0xa9, 0xe8, 0xa2, 0x6f, 0xc3, 0xb0, 0x72, 0xaf, 0x12, + 0x87, 0x4e, 0xe7, 0x20, 0xbd, 0x49, 0x0a, 0x5c, 0xe8, 0x19, 0xbb, 0xf6, 0xc5, 0xe4, 0xec, 0xdf, + 0x2e, 0x18, 0x0d, 0xf2, 0x49, 0x5c, 0x85, 0x21, 0x27, 0x64, 0x81, 0xc3, 0xeb, 0x9d, 0x24, 0xda, + 0xa9, 0x66, 0x98, 0x8b, 0xdb, 0x9c, 0xa8, 0x89, 0x15, 0x0d, 0x74, 0x85, 0x5b, 0x8d, 0x6e, 0x93, + 0x4e, 0xe2, 0xec, 0x14, 0x35, 0x90, 0x76, 0xa5, 0xdb, 0x04, 0x8b, 0xfa, 0xe8, 0x53, 0xdc, 0xac, + 0xf7, 0xaa, 0xe7, 0xdf, 0xf1, 0x2e, 0xfb, 0xbe, 0x0c, 0x43, 0xd4, 0x1b, 0xc1, 0x29, 0x69, 0xcc, + 0xab, 0xaa, 0x63, 0x93, 0x5a, 0x6f, 0xe1, 0xba, 0x3f, 0x07, 0x2c, 0x17, 0x8a, 0x19, 0xcd, 0x20, + 0x44, 0x04, 0x26, 0x44, 0xdc, 0x53, 0x59, 0x26, 0xc6, 0x2e, 0xf3, 0xf9, 0x6d, 0xd6, 0x8e, 0x35, + 0x40, 0x57, 0x4d, 0x12, 0x38, 0x49, 0xd3, 0xde, 0xe4, 0x87, 0xf0, 0x32, 0x71, 0xa2, 0x76, 0x40, + 0x42, 0xf4, 0x71, 0x98, 0x4e, 0xbf, 0x8c, 0x85, 0x22, 0xc5, 0x62, 0xdc, 0xf3, 0xa9, 0xbd, 0xdd, + 0xd2, 0x74, 0x35, 0x07, 0x07, 0xe7, 0xd6, 0xb6, 0x7f, 0xcd, 0x02, 0xe6, 0x43, 0x7e, 0x08, 0x9c, + 0xcf, 0xc7, 0x4c, 0xce, 0x67, 0x3a, 0x6f, 0x3a, 0x73, 0x98, 0x9e, 0x17, 0xf9, 0x1a, 0xae, 0x04, + 0xfe, 0xdd, 0x1d, 0x61, 0xf5, 0xd5, 0xfd, 0x19, 0x67, 0x7f, 0xd9, 0x02, 0x96, 0x38, 0x08, 0xf3, + 0x57, 0xbb, 0x54, 0x70, 0x74, 0x37, 0x68, 0xf8, 0x38, 0x0c, 0xad, 0x8b, 0xe1, 0xcf, 0x10, 0x3a, + 0x19, 0x1d, 0x36, 0x69, 0xcb, 0x49, 0x13, 0xbe, 0xa0, 0xe2, 0x1f, 0x56, 0xd4, 0xec, 0xff, 0xd2, + 0x82, 0x99, 0xfc, 0x6a, 0xe8, 0x06, 0x9c, 0x08, 0x48, 0xad, 0x1d, 0x84, 0x74, 0x4b, 0x88, 0x07, + 0x90, 0x70, 0xa7, 0xe2, 0x53, 0xfd, 0xc8, 0xde, 0x6e, 0xe9, 0x04, 0xce, 0x46, 0xc1, 0x79, 0x75, + 0xd1, 0x2b, 0x30, 0xde, 0x0e, 0x39, 0xe7, 0xc7, 0x98, 0xae, 0x50, 0x44, 0xa7, 0x66, 0x1e, 0x47, + 0x37, 0x0c, 0x08, 0x4e, 0x60, 0xda, 0x3f, 0xc0, 0x97, 0xa3, 0x0a, 0x50, 0xdd, 0x84, 0x29, 0x4f, + 0xfb, 0x4f, 0x6f, 0x40, 0xf9, 0xd4, 0x7f, 0xbc, 0xdb, 0xad, 0xcf, 0xae, 0x4b, 0xcd, 0xcb, 0x3d, + 0x41, 0x06, 0xa7, 0x29, 0xdb, 0xbf, 0x68, 0xc1, 0x09, 0x1d, 0x51, 0x73, 0xa4, 0xeb, 0xa6, 0x05, + 0x5c, 0x84, 0x21, 0xbf, 0x45, 0x02, 0x27, 0xf2, 0x03, 0x71, 0xcd, 0x9d, 0x97, 0x2b, 0xf4, 0xba, + 0x28, 0xdf, 0x17, 0x09, 0x73, 0x24, 0x75, 0x59, 0x8e, 0x55, 0x4d, 0x64, 0xc3, 0x00, 0x13, 0x20, + 0x86, 0xc2, 0x65, 0x92, 0x1d, 0x5a, 0xcc, 0xb2, 0x25, 0xc4, 0x02, 0x62, 0xff, 0xa3, 0xc5, 0xd7, + 0xa7, 0xde, 0x75, 0xf4, 0x2e, 0x4c, 0x36, 0x9d, 0xa8, 0xb6, 0xb9, 0x74, 0xb7, 0x15, 0x70, 0xe5, + 0xae, 0x1c, 0xa7, 0x67, 0xba, 0x8d, 0x93, 0xf6, 0x91, 0xb1, 0x69, 0xf5, 0x4a, 0x82, 0x18, 0x4e, + 0x91, 0x47, 0xb7, 0x61, 0x84, 0x95, 0x31, 0x6f, 0xe0, 0xb0, 0x13, 0x2f, 0x93, 0xd7, 0x9a, 0x32, + 0x0e, 0x5a, 0x89, 0xe9, 0x60, 0x9d, 0xa8, 0xfd, 0xd5, 0x22, 0x3f, 0x34, 0xd8, 0xdb, 0xe3, 0x29, + 0x18, 0x6c, 0xf9, 0xf5, 0x85, 0xf2, 0x22, 0x16, 0xb3, 0xa0, 0xee, 0xbd, 0x0a, 0x2f, 0xc6, 0x12, + 0x8e, 0xce, 0xc3, 0x90, 0xf8, 0x29, 0x95, 0xf1, 0x6c, 0x8f, 0x08, 0xbc, 0x10, 0x2b, 0x28, 0x7a, + 0x1e, 0xa0, 0x15, 0xf8, 0xdb, 0x6e, 0x9d, 0x45, 0x7f, 0x2a, 0x9a, 0x76, 0x7d, 0x15, 0x05, 0xc1, + 0x1a, 0x16, 0x7a, 0x15, 0xc6, 0xda, 0x5e, 0xc8, 0xf9, 0x27, 0x2d, 0xc6, 0xbe, 0xb2, 0x38, 0xbb, + 0xa1, 0x03, 0xb1, 0x89, 0x8b, 0xe6, 0x60, 0x20, 0x72, 0x98, 0x9d, 0x5a, 0x7f, 0xbe, 0xf9, 0xfd, + 0x1a, 0xc5, 0xd0, 0xb3, 0xd9, 0xd1, 0x0a, 0x58, 0x54, 0x44, 0x6f, 0x4b, 0xc7, 0x7c, 0x7e, 0x13, + 0x09, 0xbf, 0x97, 0xde, 0x6e, 0x2d, 0xcd, 0x2d, 0x5f, 0xf8, 0xd3, 0x18, 0xb4, 0xd0, 0x2b, 0x00, + 0xe4, 0x6e, 0x44, 0x02, 0xcf, 0x69, 0x28, 0xeb, 0x52, 0xc5, 0xc8, 0x2c, 0xfa, 0xab, 0x7e, 0x74, + 0x23, 0x24, 0x4b, 0x0a, 0x03, 0x6b, 0xd8, 0xf6, 0x8f, 0x8e, 0x00, 0xc4, 0x0f, 0x0d, 0x74, 0x0f, + 0x86, 0x6a, 0x4e, 0xcb, 0xa9, 0xf1, 0x54, 0xad, 0xc5, 0x3c, 0x7f, 0xe9, 0xb8, 0xc6, 0xec, 0x82, + 0x40, 0xe7, 0xca, 0x1b, 0x19, 0xa6, 0x7c, 0x48, 0x16, 0x77, 0x55, 0xd8, 0xa8, 0xf6, 0xd0, 0x17, + 0x2c, 0x18, 0x11, 0xd1, 0x95, 0xd8, 0x0c, 0x15, 0xf2, 0xf5, 0x6d, 0x5a, 0xfb, 0x73, 0x71, 0x0d, + 0xde, 0x85, 0x17, 0xe4, 0x0a, 0xd5, 0x20, 0x5d, 0x7b, 0xa1, 0x37, 0x8c, 0x3e, 0x2c, 0xdf, 0xb6, + 0x45, 0x63, 0x28, 0xd5, 0xdb, 0x76, 0x98, 0x5d, 0x35, 0xfa, 0xb3, 0xf6, 0x86, 0xf1, 0xac, 0xed, + 0xcb, 0xf7, 0x3c, 0x36, 0xf8, 0xed, 0x6e, 0x2f, 0x5a, 0x54, 0xd1, 0xa3, 0x90, 0xf4, 0xe7, 0xbb, + 0xcb, 0x6a, 0x0f, 0xbb, 0x2e, 0x11, 0x48, 0x3e, 0x0b, 0x13, 0x75, 0x93, 0x6b, 0x11, 0x2b, 0xf1, + 0xc9, 0x3c, 0xba, 0x09, 0x26, 0x27, 0xe6, 0x53, 0x12, 0x00, 0x9c, 0x24, 0x8c, 0x2a, 0x3c, 0x28, + 0x4d, 0xd9, 0x5b, 0xf7, 0x85, 0xef, 0x95, 0x9d, 0x3b, 0x97, 0x3b, 0x61, 0x44, 0x9a, 0x14, 0x33, + 0x66, 0x12, 0x56, 0x45, 0x5d, 0xac, 0xa8, 0xa0, 0x37, 0x61, 0x80, 0xf9, 0x4b, 0x86, 0xd3, 0x43, + 0xf9, 0x6a, 0x0d, 0x33, 0xfa, 0x6a, 0xbc, 0x21, 0xd9, 0xdf, 0x10, 0x0b, 0x0a, 0xe8, 0x8a, 0xf4, + 0x46, 0x0e, 0xcb, 0xde, 0x8d, 0x90, 0x30, 0x6f, 0xe4, 0xe1, 0xf9, 0xc7, 0x63, 0x47, 0x63, 0x5e, + 0x9e, 0x99, 0xf3, 0xd6, 0xa8, 0x49, 0xd9, 0x3e, 0xf1, 0x5f, 0xa6, 0xd2, 0x15, 0xb1, 0xe2, 0x32, + 0xbb, 0x67, 0xa6, 0xdb, 0x8d, 0x87, 0xf3, 0xa6, 0x49, 0x02, 0x27, 0x69, 0x52, 0x16, 0x9a, 0xef, + 0x7a, 0xe1, 0xbd, 0xd5, 0xed, 0xec, 0xe0, 0x92, 0x03, 0x76, 0x1b, 0xf1, 0x12, 0x2c, 0xea, 0x23, + 0x17, 0x26, 0x02, 0x83, 0xbd, 0x90, 0x21, 0xde, 0xce, 0xf5, 0xc6, 0xc4, 0x68, 0xc9, 0x03, 0x4c, + 0x32, 0x38, 0x49, 0x17, 0xbd, 0xa9, 0x31, 0x4a, 0x63, 0x9d, 0x5f, 0xfe, 0xdd, 0x58, 0xa3, 0x99, + 0x2d, 0x18, 0x33, 0x0e, 0x9b, 0x87, 0xaa, 0x82, 0xf4, 0x60, 0x32, 0x79, 0xb2, 0x3c, 0x54, 0xcd, + 0xe3, 0x2b, 0x30, 0xce, 0x36, 0xc2, 0x1d, 0xa7, 0x25, 0x8e, 0xe2, 0xf3, 0xc6, 0x51, 0x6c, 0x9d, + 0x2f, 0xf2, 0x81, 0x91, 0x43, 0x10, 0x1f, 0x9c, 0xf6, 0xaf, 0xf4, 0x8b, 0xca, 0x6a, 0x17, 0xa1, + 0x0b, 0x30, 0x2c, 0x3a, 0xa0, 0x32, 0x70, 0xa9, 0x83, 0x61, 0x45, 0x02, 0x70, 0x8c, 0xc3, 0x12, + 0xaf, 0xb1, 0xea, 0x9a, 0x87, 0x42, 0x9c, 0x78, 0x4d, 0x41, 0xb0, 0x86, 0x45, 0x1f, 0xbf, 0xb7, + 0x7d, 0x3f, 0x52, 0x77, 0xb0, 0xda, 0x6a, 0xf3, 0xac, 0x14, 0x0b, 0x28, 0xbd, 0x7b, 0xb7, 0x48, + 0xe0, 0x91, 0x86, 0x99, 0x82, 0x42, 0xdd, 0xbd, 0x57, 0x75, 0x20, 0x36, 0x71, 0x29, 0x07, 0xe1, + 0x87, 0x6c, 0xef, 0x8a, 0x27, 0x76, 0xec, 0xf1, 0x51, 0xe5, 0xb1, 0x2b, 0x24, 0x1c, 0x7d, 0x02, + 0x4e, 0xa8, 0x70, 0x8f, 0x62, 0x65, 0xca, 0x16, 0x07, 0x0c, 0x89, 0xd8, 0x89, 0x85, 0x6c, 0x34, + 0x9c, 0x57, 0x1f, 0xbd, 0x0e, 0xe3, 0xe2, 0x19, 0x26, 0x29, 0x0e, 0x9a, 0xe6, 0x8b, 0x57, 0x0d, + 0x28, 0x4e, 0x60, 0xcb, 0x24, 0x1a, 0xec, 0x7d, 0x22, 0x29, 0x0c, 0xa5, 0x93, 0x68, 0xe8, 0x70, + 0x9c, 0xaa, 0x81, 0xe6, 0x60, 0x82, 0xb3, 0x9d, 0xae, 0xb7, 0xc1, 0xe7, 0x44, 0xf8, 0x93, 0xaa, + 0x0d, 0x79, 0xdd, 0x04, 0xe3, 0x24, 0x3e, 0xba, 0x04, 0xa3, 0x4e, 0x50, 0xdb, 0x74, 0x23, 0x52, + 0xa3, 0xbb, 0x8a, 0x59, 0x10, 0x6a, 0xf6, 0x9f, 0x73, 0x1a, 0x0c, 0x1b, 0x98, 0xe8, 0x0d, 0xe8, + 0x0b, 0xef, 0x38, 0x2d, 0x71, 0xfa, 0xe4, 0x1f, 0xe5, 0x6a, 0x05, 0x73, 0xd3, 0x2f, 0xfa, 0x1f, + 0xb3, 0x9a, 0xf6, 0x3d, 0x38, 0x92, 0x11, 0x16, 0x87, 0x2e, 0x3d, 0xa7, 0xe5, 0xca, 0x51, 0x49, + 0xb8, 0x69, 0xcc, 0x55, 0xca, 0x72, 0x3c, 0x34, 0x2c, 0xba, 0xbe, 0x59, 0xf8, 0x1c, 0x2d, 0xdd, + 0xb8, 0x5a, 0xdf, 0xcb, 0x12, 0x80, 0x63, 0x1c, 0xfb, 0x5f, 0x0b, 0x30, 0x91, 0xa1, 0x1e, 0x64, + 0x29, 0xaf, 0x13, 0xef, 0xbc, 0x38, 0xc3, 0xb5, 0x99, 0xd5, 0xa5, 0x70, 0x80, 0xac, 0x2e, 0xc5, + 0x6e, 0x59, 0x5d, 0xfa, 0xde, 0x4b, 0x56, 0x17, 0x73, 0xc4, 0xfa, 0x7b, 0x1a, 0xb1, 0x8c, 0x4c, + 0x30, 0x03, 0x07, 0xcc, 0x04, 0x63, 0x0c, 0xfa, 0x60, 0x0f, 0x83, 0xfe, 0xd3, 0x05, 0x98, 0x4c, + 0x6a, 0x16, 0x0f, 0x41, 0x3a, 0xff, 0xa6, 0x21, 0x9d, 0x3f, 0xdf, 0x4b, 0x04, 0x81, 0x5c, 0x49, + 0x3d, 0x4e, 0x48, 0xea, 0x9f, 0xee, 0x89, 0x5a, 0x67, 0xa9, 0xfd, 0x2f, 0x15, 0xe0, 0x58, 0xa6, + 0xc2, 0xf5, 0x10, 0xc6, 0xe6, 0xba, 0x31, 0x36, 0xcf, 0xf5, 0x1c, 0x5d, 0x21, 0x77, 0x80, 0x6e, + 0x25, 0x06, 0xe8, 0x42, 0xef, 0x24, 0x3b, 0x8f, 0xd2, 0x37, 0x8b, 0x70, 0x26, 0xb3, 0x5e, 0x2c, + 0xdc, 0x5e, 0x36, 0x84, 0xdb, 0xcf, 0x27, 0x84, 0xdb, 0x76, 0xe7, 0xda, 0x0f, 0x46, 0xda, 0x2d, + 0xa2, 0x0c, 0xb0, 0x58, 0x29, 0xf7, 0x29, 0xe9, 0x36, 0xa2, 0x0c, 0x28, 0x42, 0xd8, 0xa4, 0xfb, + 0xbd, 0x24, 0xe1, 0xfe, 0x1f, 0x2d, 0x38, 0x99, 0x39, 0x37, 0x87, 0x20, 0x67, 0x5c, 0x35, 0xe5, + 0x8c, 0x4f, 0xf5, 0xbc, 0x5a, 0x73, 0x04, 0x8f, 0x5f, 0x1c, 0xc8, 0xf9, 0x16, 0x26, 0xfe, 0xb8, + 0x0e, 0x23, 0x4e, 0xad, 0x46, 0xc2, 0x70, 0xc5, 0xaf, 0xab, 0x04, 0x10, 0xcf, 0xb1, 0xc7, 0x69, + 0x5c, 0xbc, 0xbf, 0x5b, 0x9a, 0x49, 0x92, 0x88, 0xc1, 0x58, 0xa7, 0x80, 0x3e, 0x05, 0x43, 0xa1, + 0xcc, 0xdd, 0xd9, 0x77, 0xff, 0xb9, 0x3b, 0x19, 0x27, 0xa9, 0xc4, 0x3b, 0x8a, 0x24, 0xfa, 0x7e, + 0x3d, 0x6a, 0x55, 0x07, 0xc1, 0x26, 0xef, 0xe4, 0x7d, 0xc4, 0xae, 0x7a, 0x1e, 0x60, 0x5b, 0xbd, + 0xa3, 0x92, 0xa2, 0x1b, 0xed, 0x85, 0xa5, 0x61, 0xa1, 0x37, 0x60, 0x32, 0xe4, 0x01, 0x5b, 0x63, + 0x13, 0x19, 0xbe, 0x16, 0x59, 0xcc, 0xbb, 0x6a, 0x02, 0x86, 0x53, 0xd8, 0x68, 0x59, 0xb6, 0xca, + 0x8c, 0xa1, 0xf8, 0xf2, 0x3c, 0x17, 0xb7, 0x28, 0x0c, 0xa2, 0x8e, 0x26, 0x27, 0x81, 0x0d, 0xbf, + 0x56, 0x13, 0x7d, 0x0a, 0x80, 0x2e, 0x22, 0x21, 0xc2, 0x19, 0xcc, 0x3f, 0x42, 0xe9, 0xd9, 0x52, + 0xcf, 0xf4, 0xc0, 0x60, 0xe1, 0x01, 0x16, 0x15, 0x11, 0xac, 0x11, 0x44, 0x0e, 0x8c, 0xc5, 0xff, + 0xe2, 0xac, 0xf4, 0xe7, 0x73, 0x5b, 0x48, 0x12, 0x67, 0xea, 0x8d, 0x45, 0x9d, 0x04, 0x36, 0x29, + 0xa2, 0x4f, 0xc2, 0xc9, 0xed, 0x5c, 0xbb, 0x23, 0xce, 0x4b, 0xb2, 0x34, 0xf3, 0xf9, 0xd6, 0x46, + 0xf9, 0xf5, 0xed, 0xff, 0x09, 0xe0, 0x91, 0x0e, 0x27, 0x3d, 0x9a, 0x33, 0x6d, 0x06, 0x9e, 0x49, + 0xca, 0x55, 0x66, 0x32, 0x2b, 0x1b, 0x82, 0x96, 0xc4, 0x86, 0x2a, 0xbc, 0xe7, 0x0d, 0xf5, 0x13, + 0x96, 0xf6, 0xcc, 0xe2, 0x16, 0xe5, 0x1f, 0x3b, 0xe0, 0x0d, 0xf6, 0x00, 0x45, 0x60, 0xeb, 0x19, + 0x72, 0xa4, 0xe7, 0x7b, 0xee, 0x4e, 0xef, 0x82, 0xa5, 0xdf, 0xc9, 0x0e, 0x71, 0xcf, 0x45, 0x4c, + 0x97, 0x0f, 0xfa, 0xfd, 0x87, 0x15, 0xee, 0xfe, 0x1b, 0x16, 0x9c, 0x4c, 0x15, 0xf3, 0x3e, 0x90, + 0x50, 0x44, 0xe9, 0x5b, 0x7d, 0xcf, 0x9d, 0x97, 0x04, 0xf9, 0x37, 0x5c, 0x11, 0xdf, 0x70, 0x32, + 0x17, 0x2f, 0xd9, 0xf5, 0x2f, 0xfd, 0x7d, 0xe9, 0x08, 0x6b, 0xc0, 0x44, 0xc4, 0xf9, 0x5d, 0x47, + 0x2d, 0x38, 0x5b, 0x6b, 0x07, 0x41, 0xbc, 0x58, 0x33, 0x36, 0x27, 0x7f, 0x2d, 0x3e, 0xbe, 0xb7, + 0x5b, 0x3a, 0xbb, 0xd0, 0x05, 0x17, 0x77, 0xa5, 0x86, 0x3c, 0x40, 0xcd, 0x94, 0x75, 0x1f, 0x3b, + 0x00, 0x72, 0xa4, 0x40, 0x69, 0x5b, 0x40, 0x6e, 0xa7, 0x9b, 0x61, 0x23, 0x98, 0x41, 0xf9, 0x70, + 0x65, 0x37, 0xdf, 0x99, 0x78, 0xfa, 0x33, 0xd7, 0xe0, 0x4c, 0xe7, 0xc5, 0x74, 0xa0, 0x10, 0x14, + 0x7f, 0x63, 0xc1, 0xe9, 0x8e, 0x71, 0xce, 0xbe, 0x0b, 0x1f, 0x0b, 0xf6, 0xe7, 0x2d, 0x78, 0x34, + 0xb3, 0x46, 0xd2, 0x79, 0xb0, 0x46, 0x0b, 0x35, 0x63, 0xd8, 0x38, 0xe2, 0x8f, 0x04, 0xe0, 0x18, + 0xc7, 0xb0, 0x17, 0x2d, 0x74, 0xb5, 0x17, 0xfd, 0x53, 0x0b, 0x52, 0x57, 0xfd, 0x21, 0x70, 0x9e, + 0x65, 0x93, 0xf3, 0x7c, 0xbc, 0x97, 0xd1, 0xcc, 0x61, 0x3a, 0xff, 0x79, 0x02, 0x8e, 0xe7, 0x78, + 0x90, 0x6f, 0xc3, 0xd4, 0x46, 0x8d, 0x98, 0x21, 0x43, 0x3a, 0x85, 0xd2, 0xeb, 0x18, 0x5f, 0x64, + 0xfe, 0xd8, 0xde, 0x6e, 0x69, 0x2a, 0x85, 0x82, 0xd3, 0x4d, 0xa0, 0xcf, 0x5b, 0x70, 0xd4, 0xb9, + 0x13, 0x2e, 0xd1, 0x17, 0x84, 0x5b, 0x9b, 0x6f, 0xf8, 0xb5, 0x2d, 0xca, 0x98, 0xc9, 0x6d, 0xf5, + 0x62, 0xa6, 0x28, 0xfc, 0x56, 0x35, 0x85, 0x6f, 0x34, 0x3f, 0xbd, 0xb7, 0x5b, 0x3a, 0x9a, 0x85, + 0x85, 0x33, 0xdb, 0x42, 0x58, 0xe4, 0x38, 0x73, 0xa2, 0xcd, 0x4e, 0x41, 0x6d, 0xb2, 0x5c, 0xfd, + 0x39, 0x4b, 0x2c, 0x21, 0x58, 0xd1, 0x41, 0x9f, 0x81, 0xe1, 0x0d, 0x19, 0xbf, 0x22, 0x83, 0xe5, + 0x8e, 0x07, 0xb2, 0x73, 0x54, 0x0f, 0x6e, 0x80, 0xa3, 0x90, 0x70, 0x4c, 0x14, 0xbd, 0x0e, 0x45, + 0x6f, 0x3d, 0x14, 0xa1, 0xf5, 0xb2, 0xed, 0x80, 0x4d, 0x4b, 0x6b, 0x1e, 0x3a, 0x6a, 0x75, 0xb9, + 0x8a, 0x69, 0x45, 0x74, 0x05, 0x8a, 0xc1, 0xed, 0xba, 0xd0, 0xe3, 0x64, 0x6e, 0x52, 0x3c, 0xbf, + 0x98, 0xd3, 0x2b, 0x46, 0x09, 0xcf, 0x2f, 0x62, 0x4a, 0x02, 0x55, 0xa0, 0x9f, 0xb9, 0x5d, 0x0b, + 0xd6, 0x36, 0xf3, 0x29, 0xdf, 0x21, 0x7c, 0x01, 0xf7, 0x87, 0x64, 0x08, 0x98, 0x13, 0x42, 0x6b, + 0x30, 0x50, 0x73, 0xbd, 0x3a, 0x09, 0x04, 0x2f, 0xfb, 0xe1, 0x4c, 0x8d, 0x0d, 0xc3, 0xc8, 0xa1, + 0xc9, 0x15, 0x18, 0x0c, 0x03, 0x0b, 0x5a, 0x8c, 0x2a, 0x69, 0x6d, 0xae, 0xcb, 0x1b, 0x2b, 0x9b, + 0x2a, 0x69, 0x6d, 0x2e, 0x57, 0x3b, 0x52, 0x65, 0x18, 0x58, 0xd0, 0x42, 0xaf, 0x40, 0x61, 0xbd, + 0x26, 0x5c, 0xaa, 0x33, 0xc5, 0x9b, 0x66, 0xf4, 0xaf, 0xf9, 0x81, 0xbd, 0xdd, 0x52, 0x61, 0x79, + 0x01, 0x17, 0xd6, 0x6b, 0x68, 0x15, 0x06, 0xd7, 0x79, 0xbc, 0x20, 0x21, 0x1f, 0x7d, 0x32, 0x3b, + 0x94, 0x51, 0x2a, 0xa4, 0x10, 0xf7, 0x6d, 0x15, 0x00, 0x2c, 0x89, 0xb0, 0x94, 0x5b, 0x2a, 0xee, + 0x91, 0x08, 0xbb, 0x3a, 0x7b, 0xb0, 0x58, 0x55, 0xfc, 0xa9, 0x11, 0x47, 0x4f, 0xc2, 0x1a, 0x45, + 0xba, 0xaa, 0x9d, 0x7b, 0xed, 0x80, 0xe5, 0xe4, 0x10, 0x8a, 0x99, 0xcc, 0x55, 0x3d, 0x27, 0x91, + 0x3a, 0xad, 0x6a, 0x85, 0x84, 0x63, 0xa2, 0x68, 0x0b, 0xc6, 0xb6, 0xc3, 0xd6, 0x26, 0x91, 0x5b, + 0x9a, 0x85, 0xeb, 0xcb, 0xe1, 0x66, 0x6f, 0x0a, 0x44, 0x37, 0x88, 0xda, 0x4e, 0x23, 0x75, 0x0a, + 0xb1, 0x67, 0xcd, 0x4d, 0x9d, 0x18, 0x36, 0x69, 0xd3, 0xe1, 0x7f, 0xb7, 0xed, 0xdf, 0xde, 0x89, + 0x88, 0x88, 0x96, 0x9a, 0x39, 0xfc, 0x6f, 0x71, 0x94, 0xf4, 0xf0, 0x0b, 0x00, 0x96, 0x44, 0xd0, + 0x4d, 0x31, 0x3c, 0xec, 0xf4, 0x9c, 0xcc, 0x0f, 0xc5, 0x3e, 0x27, 0x91, 0x72, 0x06, 0x85, 0x9d, + 0x96, 0x31, 0x29, 0x76, 0x4a, 0xb6, 0x36, 0xfd, 0xc8, 0xf7, 0x12, 0x27, 0xf4, 0x54, 0xfe, 0x29, + 0x59, 0xc9, 0xc0, 0x4f, 0x9f, 0x92, 0x59, 0x58, 0x38, 0xb3, 0x2d, 0x54, 0x87, 0xf1, 0x96, 0x1f, + 0x44, 0x77, 0xfc, 0x40, 0xae, 0x2f, 0xd4, 0x41, 0x50, 0x6a, 0x60, 0x8a, 0x16, 0x99, 0x59, 0x90, + 0x09, 0xc1, 0x09, 0x9a, 0xe8, 0xe3, 0x30, 0x18, 0xd6, 0x9c, 0x06, 0x29, 0x5f, 0x9f, 0x3e, 0x92, + 0x7f, 0xfd, 0x54, 0x39, 0x4a, 0xce, 0xea, 0xe2, 0xe1, 0x9e, 0x38, 0x0a, 0x96, 0xe4, 0xd0, 0x32, + 0xf4, 0xb3, 0x54, 0xd6, 0x2c, 0xb4, 0x6f, 0x4e, 0x44, 0xf9, 0x94, 0x53, 0x0f, 0x3f, 0x9b, 0x58, + 0x31, 0xe6, 0xd5, 0xe9, 0x1e, 0x10, 0x92, 0x02, 0x3f, 0x9c, 0x3e, 0x96, 0xbf, 0x07, 0x84, 0x80, + 0xe1, 0x7a, 0xb5, 0xd3, 0x1e, 0x50, 0x48, 0x38, 0x26, 0x4a, 0x4f, 0x66, 0x7a, 0x9a, 0x1e, 0xef, + 0x60, 0xb0, 0x99, 0x7b, 0x96, 0xb2, 0x93, 0x99, 0x9e, 0xa4, 0x94, 0x84, 0xfd, 0xc7, 0x43, 0x69, + 0x9e, 0x85, 0x49, 0x98, 0xfe, 0x63, 0x2b, 0x65, 0xb1, 0xf1, 0x91, 0x5e, 0x05, 0xde, 0x0f, 0xf0, + 0xe1, 0xfa, 0x79, 0x0b, 0x8e, 0xb7, 0x32, 0x3f, 0x44, 0x30, 0x00, 0xbd, 0xc9, 0xcd, 0xf9, 0xa7, + 0xab, 0x30, 0xd0, 0xd9, 0x70, 0x9c, 0xd3, 0x52, 0x52, 0x38, 0x50, 0x7c, 0xcf, 0xc2, 0x81, 0x15, + 0x18, 0xaa, 0xf1, 0x97, 0x9c, 0x4c, 0x5f, 0xd0, 0x53, 0x10, 0x53, 0xae, 0xa7, 0x15, 0x15, 0xb1, + 0x22, 0x81, 0x7e, 0xd2, 0x82, 0xd3, 0xc9, 0xae, 0x63, 0xc2, 0xc0, 0xc2, 0x5c, 0x93, 0x8b, 0xb5, + 0x96, 0xc5, 0xf7, 0xa7, 0xf8, 0x7f, 0x03, 0x79, 0xbf, 0x1b, 0x02, 0xee, 0xdc, 0x18, 0x5a, 0xcc, + 0x90, 0xab, 0x0d, 0x98, 0x3a, 0xc9, 0x1e, 0x64, 0x6b, 0x2f, 0xc2, 0x68, 0xd3, 0x6f, 0x7b, 0x91, + 0xb0, 0xba, 0x14, 0xa6, 0x5b, 0xcc, 0x64, 0x69, 0x45, 0x2b, 0xc7, 0x06, 0x56, 0x42, 0x22, 0x37, + 0x74, 0xdf, 0x12, 0xb9, 0x77, 0x60, 0xd4, 0xd3, 0x1c, 0x12, 0x3a, 0xbd, 0x60, 0x85, 0x74, 0x51, + 0xc3, 0xe6, 0xbd, 0xd4, 0x4b, 0xb0, 0x41, 0xad, 0xb3, 0xb4, 0x0c, 0xde, 0x9b, 0xb4, 0xec, 0x50, + 0x9f, 0xc4, 0xf6, 0x6f, 0x16, 0x32, 0x5e, 0x0c, 0x5c, 0x2a, 0xf7, 0x9a, 0x29, 0x95, 0x3b, 0x97, + 0x94, 0xca, 0xa5, 0x54, 0x55, 0x86, 0x40, 0xae, 0xf7, 0x1c, 0x9a, 0x3d, 0x07, 0xa6, 0xfe, 0x61, + 0x0b, 0x4e, 0x30, 0xdd, 0x07, 0x6d, 0xe0, 0x3d, 0xeb, 0x3b, 0x98, 0x41, 0xec, 0xb5, 0x6c, 0x72, + 0x38, 0xaf, 0x1d, 0xbb, 0x01, 0x67, 0xbb, 0xdd, 0xbb, 0xcc, 0xbe, 0xb8, 0xae, 0xcc, 0x2b, 0x62, + 0xfb, 0xe2, 0x7a, 0x79, 0x11, 0x33, 0x48, 0xaf, 0x61, 0x17, 0xed, 0xff, 0xdb, 0x82, 0x62, 0xc5, + 0xaf, 0x1f, 0xc2, 0x8b, 0xfe, 0x63, 0xc6, 0x8b, 0xfe, 0x91, 0xec, 0x1b, 0xbf, 0x9e, 0xab, 0xec, + 0x5b, 0x4a, 0x28, 0xfb, 0x4e, 0xe7, 0x11, 0xe8, 0xac, 0xda, 0xfb, 0xe5, 0x22, 0x8c, 0x54, 0xfc, + 0xba, 0xda, 0x67, 0xff, 0xfd, 0xfd, 0xb8, 0x11, 0xe5, 0x66, 0xcd, 0xd2, 0x28, 0x33, 0x7b, 0x62, + 0x19, 0xf5, 0xe2, 0xbb, 0xcc, 0x9b, 0xe8, 0x16, 0x71, 0x37, 0x36, 0x23, 0x52, 0x4f, 0x7e, 0xce, + 0xe1, 0x79, 0x13, 0x7d, 0xab, 0x08, 0x13, 0x89, 0xd6, 0x51, 0x03, 0xc6, 0x1a, 0xba, 0x2a, 0x49, + 0xac, 0xd3, 0xfb, 0xd2, 0x42, 0x09, 0x6f, 0x0c, 0xad, 0x08, 0x9b, 0xc4, 0xd1, 0x2c, 0x80, 0xa7, + 0xdb, 0xa4, 0xab, 0x00, 0xcb, 0x9a, 0x3d, 0xba, 0x86, 0x81, 0x5e, 0x82, 0x91, 0xc8, 0x6f, 0xf9, + 0x0d, 0x7f, 0x63, 0xe7, 0x2a, 0x91, 0x11, 0x39, 0x95, 0xc9, 0xf2, 0x5a, 0x0c, 0xc2, 0x3a, 0x1e, + 0xba, 0x0b, 0x53, 0x8a, 0x48, 0xf5, 0x01, 0xa8, 0xd7, 0x98, 0xd8, 0x64, 0x35, 0x49, 0x11, 0xa7, + 0x1b, 0x41, 0xaf, 0xc0, 0x38, 0xb3, 0x9d, 0x66, 0xf5, 0xaf, 0x92, 0x1d, 0x19, 0xa9, 0x99, 0x71, + 0xd8, 0x2b, 0x06, 0x04, 0x27, 0x30, 0xd1, 0x02, 0x4c, 0x35, 0xdd, 0x30, 0x51, 0x7d, 0x80, 0x55, + 0x67, 0x1d, 0x58, 0x49, 0x02, 0x71, 0x1a, 0xdf, 0xfe, 0x75, 0x31, 0xc7, 0x5e, 0xe4, 0x7e, 0xb0, + 0x1d, 0xdf, 0xdf, 0xdb, 0xf1, 0x9b, 0x16, 0x4c, 0xd2, 0xd6, 0x99, 0x41, 0xa8, 0x64, 0xa4, 0x54, + 0x2e, 0x0f, 0xab, 0x43, 0x2e, 0x8f, 0x73, 0xf4, 0xd8, 0xae, 0xfb, 0xed, 0x48, 0x48, 0x47, 0xb5, + 0x73, 0x99, 0x96, 0x62, 0x01, 0x15, 0x78, 0x24, 0x08, 0x84, 0xd7, 0xbd, 0x8e, 0x47, 0x82, 0x00, + 0x0b, 0xa8, 0x4c, 0xf5, 0xd1, 0x97, 0x9d, 0xea, 0x83, 0x47, 0x6c, 0x17, 0x76, 0x74, 0x82, 0xa5, + 0xd5, 0x22, 0xb6, 0x4b, 0x03, 0xbb, 0x18, 0xc7, 0xfe, 0x76, 0x11, 0x46, 0x2b, 0x7e, 0x3d, 0x36, + 0xec, 0x78, 0xd1, 0x30, 0xec, 0x38, 0x9b, 0x30, 0xec, 0x98, 0xd4, 0x71, 0x35, 0x33, 0x8e, 0x37, + 0x01, 0xf9, 0x22, 0x90, 0xfc, 0x65, 0xe2, 0x31, 0xbb, 0x37, 0x61, 0xa8, 0x57, 0x8c, 0xcd, 0x1e, + 0xae, 0xa7, 0x30, 0x70, 0x46, 0xad, 0x0f, 0x4c, 0x42, 0x0e, 0xd7, 0x24, 0xe4, 0x4f, 0x2c, 0xb6, + 0x02, 0x16, 0x57, 0xab, 0xdc, 0x56, 0x19, 0x5d, 0x84, 0x11, 0x76, 0x5a, 0xb2, 0x90, 0x11, 0xd2, + 0x72, 0x82, 0xa5, 0xf1, 0x5c, 0x8d, 0x8b, 0xb1, 0x8e, 0x83, 0xce, 0xc3, 0x50, 0x48, 0x9c, 0xa0, + 0xb6, 0xa9, 0xae, 0x0a, 0x61, 0xe6, 0xc0, 0xcb, 0xb0, 0x82, 0xa2, 0xb7, 0xe2, 0xc0, 0xe3, 0xc5, + 0x7c, 0xc3, 0x67, 0xbd, 0x3f, 0x7c, 0xbb, 0xe5, 0x47, 0x1b, 0xb7, 0x6f, 0x01, 0x4a, 0xe3, 0xf7, + 0xe0, 0x49, 0x56, 0x32, 0x43, 0xe3, 0x0e, 0xa7, 0xc2, 0xe2, 0xfe, 0x9b, 0x05, 0xe3, 0x15, 0xbf, + 0x4e, 0x8f, 0x81, 0xef, 0xa5, 0x3d, 0xaf, 0x67, 0x5d, 0x18, 0xe8, 0x90, 0x75, 0xe1, 0x31, 0xe8, + 0xaf, 0xf8, 0xf5, 0x2e, 0xe1, 0x7b, 0x7f, 0xc5, 0x82, 0xc1, 0x8a, 0x5f, 0x3f, 0x04, 0x25, 0xce, + 0x6b, 0xa6, 0x12, 0xe7, 0x44, 0xce, 0xba, 0xc9, 0xd1, 0xdb, 0xfc, 0x79, 0x1f, 0x8c, 0xd1, 0x7e, + 0xfa, 0x1b, 0x72, 0x2a, 0x8d, 0x61, 0xb3, 0x7a, 0x18, 0x36, 0xfa, 0xa4, 0xf0, 0x1b, 0x0d, 0xff, + 0x4e, 0x72, 0x5a, 0x97, 0x59, 0x29, 0x16, 0x50, 0xf4, 0x2c, 0x0c, 0xb5, 0x02, 0xb2, 0xed, 0xfa, + 0x82, 0x57, 0xd7, 0x54, 0x62, 0x15, 0x51, 0x8e, 0x15, 0x06, 0x7d, 0xc4, 0x87, 0xae, 0x47, 0xf9, + 0x92, 0x9a, 0xef, 0xd5, 0xb9, 0x9e, 0xa3, 0x28, 0x52, 0x83, 0x69, 0xe5, 0xd8, 0xc0, 0x42, 0xb7, + 0x60, 0x98, 0xfd, 0x67, 0xc7, 0x4e, 0xff, 0x81, 0x8f, 0x1d, 0x91, 0x2c, 0x59, 0x10, 0xc0, 0x31, + 0x2d, 0xf4, 0x3c, 0x40, 0x24, 0xd3, 0xeb, 0x84, 0x22, 0x8c, 0xab, 0x7a, 0xd7, 0xa8, 0xc4, 0x3b, + 0x21, 0xd6, 0xb0, 0xd0, 0x33, 0x30, 0x1c, 0x39, 0x6e, 0xe3, 0x9a, 0xeb, 0x31, 0x5b, 0x00, 0xda, + 0x7f, 0x91, 0xb3, 0x58, 0x14, 0xe2, 0x18, 0x4e, 0xf9, 0x4a, 0x16, 0xdd, 0x6a, 0x7e, 0x27, 0x12, + 0xe9, 0xf9, 0x8a, 0x9c, 0xaf, 0xbc, 0xa6, 0x4a, 0xb1, 0x86, 0x81, 0x36, 0xe1, 0x94, 0xeb, 0xb1, + 0x34, 0x5a, 0xa4, 0xba, 0xe5, 0xb6, 0xd6, 0xae, 0x55, 0x6f, 0x92, 0xc0, 0x5d, 0xdf, 0x99, 0x77, + 0x6a, 0x5b, 0xc4, 0xab, 0x33, 0xb1, 0xc3, 0xd0, 0xfc, 0xe3, 0xa2, 0x8b, 0xa7, 0xca, 0x1d, 0x70, + 0x71, 0x47, 0x4a, 0xc8, 0xa6, 0xdb, 0x31, 0x20, 0x4e, 0x53, 0xc8, 0x17, 0x78, 0x0a, 0x1e, 0x56, + 0x82, 0x05, 0xc4, 0x7e, 0x81, 0xed, 0x89, 0xeb, 0x55, 0xf4, 0xb4, 0x71, 0xbc, 0x1c, 0xd7, 0x8f, + 0x97, 0xfd, 0xdd, 0xd2, 0xc0, 0xf5, 0xaa, 0x16, 0xe9, 0xe8, 0x12, 0x1c, 0xab, 0xf8, 0xf5, 0x8a, + 0x1f, 0x44, 0xcb, 0x7e, 0x70, 0xc7, 0x09, 0xea, 0x72, 0x09, 0x96, 0x64, 0xac, 0x27, 0x7a, 0xc6, + 0xf6, 0xf3, 0x13, 0xc8, 0x88, 0xe3, 0xf4, 0x02, 0xe3, 0x10, 0x0f, 0xe8, 0x5a, 0x5b, 0x63, 0xbc, + 0x8a, 0x4a, 0x56, 0x77, 0xd9, 0x89, 0x08, 0xba, 0x0e, 0x63, 0x35, 0xfd, 0xda, 0x16, 0xd5, 0x9f, + 0x92, 0x97, 0x9d, 0x71, 0xa7, 0x67, 0xde, 0xf3, 0x66, 0x7d, 0xfb, 0x1b, 0x96, 0x68, 0x85, 0x4b, + 0x3e, 0xb8, 0x0d, 0x6d, 0xf7, 0x33, 0x77, 0x01, 0xa6, 0x02, 0xbd, 0x8a, 0x66, 0x8b, 0x76, 0x8c, + 0x67, 0xff, 0x49, 0x00, 0x71, 0x1a, 0x1f, 0x7d, 0x12, 0x4e, 0x1a, 0x85, 0x52, 0x2d, 0xaf, 0xe5, + 0xe0, 0x66, 0xb2, 0x21, 0x9c, 0x87, 0x84, 0xf3, 0xeb, 0xdb, 0x3f, 0x08, 0xc7, 0x93, 0xdf, 0x25, + 0xa4, 0x35, 0xf7, 0xf9, 0x75, 0x85, 0x83, 0x7d, 0x9d, 0xfd, 0x12, 0x4c, 0xd1, 0x67, 0xbc, 0x62, + 0x49, 0xd9, 0xfc, 0x75, 0x0f, 0xa7, 0xf5, 0xdb, 0x43, 0xec, 0x1a, 0x4c, 0x64, 0xa0, 0x43, 0x9f, + 0x86, 0xf1, 0x90, 0xb0, 0x18, 0x72, 0x52, 0x4a, 0xd8, 0xc1, 0x2f, 0xbe, 0xba, 0xa4, 0x63, 0xf2, + 0x97, 0x90, 0x59, 0x86, 0x13, 0xd4, 0x50, 0x13, 0xc6, 0xef, 0xb8, 0x5e, 0xdd, 0xbf, 0x13, 0x4a, + 0xfa, 0x43, 0xf9, 0x2a, 0x87, 0x5b, 0x1c, 0x33, 0xd1, 0x47, 0xa3, 0xb9, 0x5b, 0x06, 0x31, 0x9c, + 0x20, 0x4e, 0x8f, 0x9a, 0xa0, 0xed, 0xcd, 0x85, 0x37, 0x42, 0x12, 0x88, 0x08, 0x77, 0xec, 0xa8, + 0xc1, 0xb2, 0x10, 0xc7, 0x70, 0x7a, 0xd4, 0xb0, 0x3f, 0xcc, 0xb1, 0x9e, 0x9d, 0x65, 0xe2, 0xa8, + 0xc1, 0xaa, 0x14, 0x6b, 0x18, 0xf4, 0x28, 0x66, 0xff, 0x56, 0x7d, 0x0f, 0xfb, 0x7e, 0x24, 0x0f, + 0x6f, 0x96, 0xae, 0x53, 0x2b, 0xc7, 0x06, 0x56, 0x4e, 0x3c, 0xbd, 0xbe, 0x83, 0xc6, 0xd3, 0x43, + 0x51, 0x87, 0x58, 0x02, 0x3c, 0x22, 0xf4, 0xa5, 0x4e, 0xb1, 0x04, 0xf6, 0xef, 0x2b, 0xce, 0x00, + 0xe5, 0x05, 0xd6, 0xc5, 0x00, 0xf5, 0xf3, 0x80, 0x81, 0x4c, 0x29, 0x5a, 0xe5, 0xa3, 0x23, 0x61, + 0x68, 0x09, 0x06, 0xc3, 0x9d, 0xb0, 0x16, 0x35, 0xc2, 0x4e, 0x29, 0x59, 0xab, 0x0c, 0x45, 0xcb, + 0x08, 0xce, 0xab, 0x60, 0x59, 0x17, 0xd5, 0xe0, 0x88, 0xa0, 0xb8, 0xb0, 0xe9, 0x78, 0x2a, 0x51, + 0x24, 0xb7, 0x7e, 0xbc, 0xb8, 0xb7, 0x5b, 0x3a, 0x22, 0x5a, 0xd6, 0xc1, 0xfb, 0xbb, 0x25, 0xba, + 0x25, 0x33, 0x20, 0x38, 0x8b, 0x1a, 0x5f, 0xf2, 0xb5, 0x9a, 0xdf, 0x6c, 0x55, 0x02, 0x7f, 0xdd, + 0x6d, 0x90, 0x4e, 0x8a, 0xe5, 0xaa, 0x81, 0x29, 0x96, 0xbc, 0x51, 0x86, 0x13, 0xd4, 0xd0, 0x6d, + 0x98, 0x70, 0x5a, 0xad, 0xb9, 0xa0, 0xe9, 0x07, 0xb2, 0x81, 0x91, 0x7c, 0x0d, 0xc5, 0x9c, 0x89, + 0xca, 0xf3, 0x44, 0x26, 0x0a, 0x71, 0x92, 0x20, 0x1d, 0x28, 0xb1, 0xd1, 0x8c, 0x81, 0x1a, 0x8b, + 0x07, 0x4a, 0xec, 0xcb, 0x8c, 0x81, 0xca, 0x80, 0xe0, 0x2c, 0x6a, 0xf6, 0x0f, 0x30, 0xc6, 0x9f, + 0xc5, 0x9b, 0x66, 0x6e, 0x46, 0x4d, 0x18, 0x6b, 0xb1, 0x63, 0x5f, 0xe4, 0x70, 0x13, 0x47, 0xc5, + 0x8b, 0x3d, 0x0a, 0x42, 0xef, 0xb0, 0x2c, 0xb4, 0x86, 0x41, 0x6c, 0x45, 0x27, 0x87, 0x4d, 0xea, + 0xf6, 0x2f, 0xcd, 0x30, 0xd6, 0xb1, 0xca, 0xa5, 0x9b, 0x83, 0xc2, 0xe9, 0x52, 0xc8, 0x33, 0x66, + 0xf2, 0xf5, 0x08, 0xf1, 0xfa, 0x12, 0x8e, 0x9b, 0x58, 0xd6, 0x45, 0x9f, 0x82, 0x71, 0xd7, 0x73, + 0xe3, 0xec, 0xcd, 0xe1, 0xf4, 0xd1, 0xfc, 0x68, 0x5e, 0x0a, 0x4b, 0xcf, 0xef, 0xa8, 0x57, 0xc6, + 0x09, 0x62, 0xe8, 0x2d, 0x66, 0x23, 0x2a, 0x49, 0x17, 0x7a, 0x21, 0xad, 0x9b, 0x83, 0x4a, 0xb2, + 0x1a, 0x11, 0xd4, 0x86, 0x23, 0xe9, 0x2c, 0xd6, 0xe1, 0xb4, 0x9d, 0xff, 0x36, 0x4a, 0x27, 0xa2, + 0x8e, 0x13, 0xf1, 0xa5, 0x61, 0x21, 0xce, 0xa2, 0x8f, 0xae, 0x25, 0x73, 0x0c, 0x17, 0x0d, 0x0d, + 0x44, 0x2a, 0xcf, 0xf0, 0x58, 0xc7, 0xf4, 0xc2, 0x1b, 0x70, 0x5a, 0x4b, 0xd3, 0x7a, 0x39, 0x70, + 0x98, 0x8d, 0x92, 0xcb, 0x6e, 0x23, 0x8d, 0xa9, 0x7d, 0x74, 0x6f, 0xb7, 0x74, 0x7a, 0xad, 0x13, + 0x22, 0xee, 0x4c, 0x07, 0x5d, 0x87, 0x63, 0x3c, 0x16, 0xcd, 0x22, 0x71, 0xea, 0x0d, 0xd7, 0x53, + 0x5c, 0x33, 0x3f, 0xbb, 0x4e, 0xee, 0xed, 0x96, 0x8e, 0xcd, 0x65, 0x21, 0xe0, 0xec, 0x7a, 0xe8, + 0x35, 0x18, 0xae, 0x7b, 0xf2, 0x94, 0x1d, 0x30, 0x32, 0xe1, 0x0e, 0x2f, 0xae, 0x56, 0xd5, 0xf7, + 0xc7, 0x7f, 0x70, 0x5c, 0x01, 0x6d, 0x70, 0x15, 0x98, 0x92, 0x5b, 0x0e, 0xa6, 0x42, 0x94, 0x26, + 0x45, 0xfb, 0x46, 0x70, 0x07, 0xae, 0xfb, 0x55, 0x0e, 0x80, 0x46, 0xdc, 0x07, 0x83, 0x30, 0x7a, + 0x13, 0x90, 0xc8, 0xb8, 0x34, 0x57, 0x63, 0x09, 0x02, 0x35, 0xbb, 0x54, 0x25, 0x42, 0xa8, 0xa6, + 0x30, 0x70, 0x46, 0x2d, 0x74, 0x85, 0x1e, 0x8f, 0x7a, 0xa9, 0x38, 0x7e, 0x55, 0xbe, 0xf5, 0x45, + 0xd2, 0x0a, 0x08, 0x33, 0xa5, 0x34, 0x29, 0xe2, 0x44, 0x3d, 0x54, 0x87, 0x53, 0x4e, 0x3b, 0xf2, + 0x99, 0x76, 0xd1, 0x44, 0x5d, 0xf3, 0xb7, 0x88, 0xc7, 0x14, 0xfb, 0x43, 0x2c, 0xf4, 0xe9, 0xa9, + 0xb9, 0x0e, 0x78, 0xb8, 0x23, 0x15, 0xfa, 0x9c, 0xa2, 0x63, 0xa1, 0x29, 0xfe, 0x0c, 0x3f, 0x75, + 0xae, 0x0d, 0x97, 0x18, 0xe8, 0x25, 0x18, 0xd9, 0xf4, 0xc3, 0x68, 0x95, 0x44, 0x77, 0xfc, 0x60, + 0x4b, 0xa4, 0x78, 0x88, 0xd3, 0xea, 0xc4, 0x20, 0xac, 0xe3, 0xa1, 0xa7, 0x60, 0x90, 0x99, 0x9d, + 0x95, 0x17, 0xd9, 0x5d, 0x3b, 0x14, 0x9f, 0x31, 0x57, 0x78, 0x31, 0x96, 0x70, 0x89, 0x5a, 0xae, + 0x2c, 0xb0, 0xe3, 0x38, 0x81, 0x5a, 0xae, 0x2c, 0x60, 0x09, 0xa7, 0xcb, 0x35, 0xdc, 0x74, 0x02, + 0x52, 0x09, 0xfc, 0x1a, 0x09, 0xb5, 0x64, 0x4e, 0x8f, 0xf0, 0x04, 0x16, 0x74, 0xb9, 0x56, 0xb3, + 0x10, 0x70, 0x76, 0x3d, 0x44, 0xd2, 0x29, 0x8a, 0xc7, 0xf3, 0xd5, 0xae, 0x69, 0x76, 0xb0, 0xc7, + 0x2c, 0xc5, 0x1e, 0x4c, 0xaa, 0xe4, 0xc8, 0x3c, 0x65, 0x45, 0x38, 0x3d, 0xc1, 0xd6, 0x76, 0xef, + 0xf9, 0x2e, 0x94, 0x22, 0xbb, 0x9c, 0xa0, 0x84, 0x53, 0xb4, 0x8d, 0xd8, 0xba, 0x93, 0x5d, 0x63, + 0xeb, 0x5e, 0x80, 0xe1, 0xb0, 0x7d, 0xbb, 0xee, 0x37, 0x1d, 0xd7, 0x63, 0xd6, 0x3b, 0xda, 0xc3, + 0xbd, 0x2a, 0x01, 0x38, 0xc6, 0x41, 0xcb, 0x30, 0xe4, 0x48, 0x2d, 0x35, 0xca, 0x0f, 0x1b, 0xa8, + 0x74, 0xd3, 0x3c, 0x92, 0x96, 0xd4, 0x4b, 0xab, 0xba, 0xe8, 0x55, 0x18, 0x13, 0xa1, 0x49, 0x78, + 0x14, 0x1e, 0x66, 0x5d, 0xa3, 0x39, 0x53, 0x57, 0x75, 0x20, 0x36, 0x71, 0xd1, 0x0d, 0x18, 0x89, + 0xfc, 0x86, 0x90, 0x71, 0x86, 0xd3, 0xc7, 0xf3, 0xa3, 0xfb, 0xae, 0x29, 0x34, 0x5d, 0x7f, 0xa2, + 0xaa, 0x62, 0x9d, 0x0e, 0x5a, 0xe3, 0xeb, 0x9d, 0xa5, 0x6e, 0x22, 0xa1, 0x48, 0x48, 0x7f, 0x3a, + 0xcf, 0xf4, 0x92, 0xa1, 0x99, 0xdb, 0x41, 0xd4, 0xc4, 0x3a, 0x19, 0x74, 0x19, 0xa6, 0x5a, 0x81, + 0xeb, 0xb3, 0x35, 0xa1, 0xb4, 0xee, 0xd3, 0x66, 0xa2, 0xd6, 0x4a, 0x12, 0x01, 0xa7, 0xeb, 0xb0, + 0xc8, 0x32, 0xa2, 0x70, 0xfa, 0x24, 0x4f, 0x36, 0xc7, 0xe5, 0x20, 0xbc, 0x0c, 0x2b, 0x28, 0x5a, + 0x61, 0x27, 0x31, 0x17, 0xe1, 0x4d, 0xcf, 0xe4, 0xc7, 0x2b, 0xd0, 0x45, 0x7d, 0x9c, 0xf7, 0x57, + 0x7f, 0x71, 0x4c, 0x01, 0xd5, 0xb5, 0x1c, 0xef, 0xf4, 0x05, 0x15, 0x4e, 0x9f, 0xea, 0x60, 0xfb, + 0x9b, 0x78, 0x2e, 0xc7, 0x0c, 0x81, 0x51, 0x1c, 0xe2, 0x04, 0x4d, 0xf4, 0x06, 0x4c, 0x8a, 0xb0, + 0x0b, 0xf1, 0x30, 0x9d, 0x8e, 0xfd, 0xa3, 0x70, 0x02, 0x86, 0x53, 0xd8, 0x3c, 0xd9, 0x9b, 0x73, + 0xbb, 0x41, 0xc4, 0xd1, 0x77, 0xcd, 0xf5, 0xb6, 0xc2, 0xe9, 0x33, 0xec, 0x7c, 0x10, 0xc9, 0xde, + 0x92, 0x50, 0x9c, 0x51, 0x03, 0xad, 0xc1, 0x64, 0x2b, 0x20, 0xa4, 0xc9, 0xde, 0x49, 0xe2, 0x3e, + 0x2b, 0xf1, 0xc0, 0x4a, 0xb4, 0x27, 0x95, 0x04, 0x6c, 0x3f, 0xa3, 0x0c, 0xa7, 0x28, 0xa0, 0x3b, + 0x30, 0xe4, 0x6f, 0x93, 0x60, 0x93, 0x38, 0xf5, 0xe9, 0xb3, 0x1d, 0xbc, 0xf6, 0xc4, 0xe5, 0x76, + 0x5d, 0xe0, 0x26, 0x8c, 0x9a, 0x64, 0x71, 0x77, 0xa3, 0x26, 0xd9, 0x18, 0xfa, 0x4f, 0x2c, 0x38, + 0x29, 0xd5, 0x84, 0xd5, 0x16, 0x1d, 0xf5, 0x05, 0xdf, 0x0b, 0xa3, 0x80, 0x87, 0x02, 0x7a, 0x34, + 0x3f, 0x3c, 0xce, 0x5a, 0x4e, 0x25, 0xa5, 0x45, 0x38, 0x99, 0x87, 0x11, 0xe2, 0xfc, 0x16, 0xe9, + 0xcb, 0x3e, 0x24, 0x91, 0x3c, 0x8c, 0xe6, 0xc2, 0xe5, 0xb7, 0x16, 0x57, 0xa7, 0x1f, 0xe3, 0x71, + 0x8c, 0xe8, 0x66, 0xa8, 0x26, 0x81, 0x38, 0x8d, 0x8f, 0x2e, 0x42, 0xc1, 0x0f, 0xa7, 0x1f, 0x67, + 0x6b, 0xfb, 0x64, 0xce, 0x38, 0x5e, 0xaf, 0x72, 0xe3, 0xd6, 0xeb, 0x55, 0x5c, 0xf0, 0x43, 0x99, + 0x70, 0x8d, 0x3e, 0x67, 0xc3, 0xe9, 0x27, 0xb8, 0xcc, 0x59, 0x26, 0x5c, 0x63, 0x85, 0x38, 0x86, + 0xa3, 0x4d, 0x98, 0x08, 0x0d, 0xb1, 0x41, 0x38, 0x7d, 0x8e, 0x8d, 0xd4, 0x13, 0x79, 0x93, 0x66, + 0x60, 0x6b, 0x99, 0x90, 0x4c, 0x2a, 0x38, 0x49, 0x96, 0xef, 0x2e, 0x4d, 0x70, 0x11, 0x4e, 0x3f, + 0xd9, 0x65, 0x77, 0x69, 0xc8, 0xfa, 0xee, 0xd2, 0x69, 0xe0, 0x04, 0x4d, 0x74, 0x43, 0x77, 0x89, + 0x3c, 0x9f, 0x6f, 0x28, 0x99, 0xe9, 0x0c, 0x39, 0x96, 0xe7, 0x08, 0x39, 0xf3, 0x7d, 0x30, 0x95, + 0xe2, 0xc2, 0x0e, 0xe2, 0x1f, 0x32, 0xb3, 0x05, 0x63, 0xc6, 0x4a, 0x7f, 0xa8, 0xe6, 0x43, 0x3f, + 0x03, 0x30, 0xac, 0xcc, 0x3a, 0x72, 0xf4, 0x6c, 0x53, 0xf7, 0xa5, 0x67, 0xbb, 0x60, 0x5a, 0x1f, + 0x9d, 0x4c, 0x5a, 0x1f, 0x0d, 0x55, 0xfc, 0xba, 0x61, 0x70, 0xb4, 0x96, 0x11, 0x41, 0x38, 0xef, + 0x8c, 0xee, 0xdd, 0x21, 0x4e, 0x53, 0x55, 0x15, 0x7b, 0x36, 0x63, 0xea, 0xeb, 0xa8, 0xfd, 0xba, + 0x0c, 0x53, 0x9e, 0xcf, 0x9e, 0x11, 0xa4, 0x2e, 0x79, 0x44, 0xc6, 0x0a, 0x0e, 0xeb, 0x11, 0xee, + 0x12, 0x08, 0x38, 0x5d, 0x87, 0x36, 0xc8, 0x79, 0xb9, 0xa4, 0xba, 0x8d, 0xb3, 0x7a, 0x58, 0x40, + 0xe9, 0xf3, 0x95, 0xff, 0x0a, 0xa7, 0x27, 0xf3, 0x9f, 0xaf, 0xbc, 0x52, 0x92, 0x5f, 0x0c, 0x25, + 0xbf, 0xc8, 0xb4, 0x4b, 0x2d, 0xbf, 0x5e, 0xae, 0x88, 0x97, 0x88, 0x16, 0xdb, 0xbf, 0x5e, 0xae, + 0x60, 0x0e, 0x43, 0x73, 0x30, 0xc0, 0x7e, 0xc8, 0xc8, 0x41, 0x79, 0x27, 0x49, 0xb9, 0xa2, 0xe5, + 0xa4, 0x65, 0x15, 0xb0, 0xa8, 0xc8, 0xb4, 0x07, 0xf4, 0xf9, 0xc6, 0xb4, 0x07, 0x83, 0xf7, 0xa9, + 0x3d, 0x90, 0x04, 0x70, 0x4c, 0x0b, 0xdd, 0x85, 0x63, 0xc6, 0x93, 0x59, 0x79, 0x08, 0x42, 0xbe, + 0x91, 0x42, 0x02, 0x79, 0xfe, 0xb4, 0xe8, 0xf4, 0xb1, 0x72, 0x16, 0x25, 0x9c, 0xdd, 0x00, 0x6a, + 0xc0, 0x54, 0x2d, 0xd5, 0xea, 0x50, 0xef, 0xad, 0xaa, 0x75, 0x91, 0x6e, 0x31, 0x4d, 0x18, 0xbd, + 0x0a, 0x43, 0xef, 0xfa, 0xdc, 0xa0, 0x50, 0xbc, 0x9e, 0x64, 0x7c, 0x9b, 0xa1, 0xb7, 0xae, 0x57, + 0x59, 0xf9, 0xfe, 0x6e, 0x69, 0xa4, 0xe2, 0xd7, 0xe5, 0x5f, 0xac, 0x2a, 0xa0, 0x1f, 0xb3, 0x60, + 0x26, 0xfd, 0x26, 0x57, 0x9d, 0x1e, 0xeb, 0xbd, 0xd3, 0xb6, 0x68, 0x74, 0x66, 0x29, 0x97, 0x1c, + 0xee, 0xd0, 0x14, 0xfa, 0x28, 0xdd, 0x4f, 0xa1, 0x7b, 0x8f, 0x88, 0x84, 0xfe, 0x8f, 0xc6, 0xfb, + 0x89, 0x96, 0xee, 0xef, 0x96, 0x26, 0xf8, 0xe1, 0xed, 0xde, 0x53, 0x59, 0x08, 0x78, 0x05, 0xf4, + 0x83, 0x70, 0x2c, 0x48, 0xcb, 0xc8, 0x89, 0x7c, 0x27, 0x3c, 0xdd, 0xcb, 0x45, 0x90, 0x9c, 0x70, + 0x9c, 0x45, 0x10, 0x67, 0xb7, 0x63, 0xff, 0xa1, 0xc5, 0x74, 0x23, 0xa2, 0x5b, 0x24, 0x6c, 0x37, + 0xa2, 0x43, 0x30, 0xe2, 0x5b, 0x32, 0x6c, 0x13, 0xee, 0xdb, 0x0a, 0xef, 0xbf, 0xb3, 0x98, 0x15, + 0xde, 0x21, 0xfa, 0x13, 0xbe, 0x05, 0x43, 0x91, 0x68, 0x4d, 0x74, 0x3d, 0xcf, 0x62, 0x48, 0x76, + 0x8a, 0x59, 0x22, 0xaa, 0x77, 0x98, 0x2c, 0xc5, 0x8a, 0x8c, 0xfd, 0x5f, 0xf3, 0x19, 0x90, 0x90, + 0x43, 0x50, 0x01, 0x2f, 0x9a, 0x2a, 0xe0, 0x52, 0x97, 0x2f, 0xc8, 0x51, 0x05, 0xff, 0x57, 0x66, + 0xbf, 0x99, 0xfc, 0xf1, 0xfd, 0x6e, 0xfe, 0x69, 0x7f, 0xd1, 0x02, 0x88, 0xd3, 0xbe, 0xf4, 0x90, + 0xc0, 0xfb, 0x12, 0x7d, 0x79, 0xf9, 0x91, 0x5f, 0xf3, 0x1b, 0x42, 0x05, 0x75, 0x2a, 0xd6, 0x42, + 0xf3, 0xf2, 0x7d, 0xed, 0x37, 0x56, 0xd8, 0xa8, 0x24, 0xe3, 0x30, 0x17, 0x63, 0xbb, 0x08, 0x23, + 0x06, 0xf3, 0x57, 0x2c, 0x38, 0x9a, 0xe5, 0x9c, 0x42, 0xdf, 0xf1, 0x5c, 0x12, 0xab, 0x4c, 0x73, + 0xd5, 0x6c, 0xde, 0x14, 0xe5, 0x58, 0x61, 0xf4, 0x9c, 0x19, 0xfd, 0x60, 0x29, 0x49, 0xae, 0xc3, + 0x58, 0x25, 0x20, 0x1a, 0x7f, 0xf1, 0x7a, 0x9c, 0x2d, 0x69, 0x78, 0xfe, 0xd9, 0x03, 0x47, 0x7c, + 0xb2, 0xbf, 0x5a, 0x80, 0xa3, 0xdc, 0xc0, 0x6c, 0x6e, 0xdb, 0x77, 0xeb, 0x15, 0xbf, 0x2e, 0x5c, + 0x8a, 0xdf, 0x86, 0xd1, 0x96, 0x26, 0x3e, 0xef, 0x14, 0x5e, 0x5f, 0x17, 0xb3, 0xc7, 0x02, 0x3f, + 0xbd, 0x14, 0x1b, 0xb4, 0x50, 0x1d, 0x46, 0xc9, 0xb6, 0x5b, 0x53, 0x96, 0x45, 0x85, 0x03, 0x5f, + 0xd2, 0xaa, 0x95, 0x25, 0x8d, 0x0e, 0x36, 0xa8, 0xf6, 0x6c, 0x16, 0xae, 0xb1, 0x68, 0x7d, 0x5d, + 0xac, 0x89, 0x7e, 0xce, 0x82, 0x13, 0x39, 0xc1, 0xf8, 0x69, 0x73, 0x77, 0x98, 0x29, 0x9f, 0x58, + 0xb6, 0xaa, 0x39, 0x6e, 0xe0, 0x87, 0x05, 0x14, 0x7d, 0x1c, 0xa0, 0x15, 0xa7, 0x30, 0xed, 0x12, + 0xb5, 0xdc, 0x88, 0x5f, 0xac, 0x85, 0xa2, 0x55, 0x99, 0x4e, 0x35, 0x5a, 0xf6, 0x57, 0xfa, 0xa0, + 0x9f, 0x19, 0x71, 0xa1, 0x0a, 0x0c, 0x6e, 0xf2, 0x48, 0x89, 0x1d, 0xe7, 0x8d, 0xe2, 0xca, 0xd0, + 0x8b, 0xf1, 0xbc, 0x69, 0xa5, 0x58, 0x92, 0x41, 0x2b, 0x70, 0x84, 0xa7, 0x67, 0x6d, 0x2c, 0x92, + 0x86, 0xb3, 0x23, 0x25, 0xd3, 0x05, 0xf6, 0xa9, 0x4a, 0x42, 0x5f, 0x4e, 0xa3, 0xe0, 0xac, 0x7a, + 0xe8, 0x75, 0x18, 0x8f, 0xdc, 0x26, 0xf1, 0xdb, 0x91, 0xa4, 0xc4, 0xf3, 0xa1, 0xaa, 0xc7, 0xd3, + 0x9a, 0x01, 0xc5, 0x09, 0x6c, 0xf4, 0x2a, 0x8c, 0xb5, 0x52, 0x32, 0xf8, 0xfe, 0x58, 0x58, 0x65, + 0xca, 0xdd, 0x4d, 0x5c, 0xe6, 0x9f, 0xd2, 0x66, 0xde, 0x38, 0x6b, 0x9b, 0x01, 0x09, 0x37, 0xfd, + 0x46, 0x9d, 0x71, 0xc0, 0xfd, 0x9a, 0x7f, 0x4a, 0x02, 0x8e, 0x53, 0x35, 0x28, 0x95, 0x75, 0xc7, + 0x6d, 0xb4, 0x03, 0x12, 0x53, 0x19, 0x30, 0xa9, 0x2c, 0x27, 0xe0, 0x38, 0x55, 0xa3, 0xbb, 0x72, + 0x61, 0xf0, 0xc1, 0x28, 0x17, 0xec, 0x5f, 0x2d, 0x80, 0x31, 0xb5, 0xdf, 0xc3, 0xd9, 0x56, 0x5f, + 0x83, 0xbe, 0x8d, 0xa0, 0x55, 0x13, 0x06, 0x8b, 0x99, 0x5f, 0x76, 0x19, 0x57, 0x16, 0xf4, 0x2f, + 0xa3, 0xff, 0x31, 0xab, 0x45, 0xf7, 0xf8, 0xb1, 0x4a, 0xe0, 0xd3, 0x4b, 0x4e, 0x06, 0x53, 0x55, + 0x6e, 0x60, 0x83, 0xf2, 0xbd, 0xde, 0x21, 0xec, 0xb8, 0xf0, 0x65, 0xe1, 0x14, 0x0c, 0xdb, 0xbe, + 0xaa, 0x78, 0xad, 0x4b, 0x2a, 0xe8, 0x22, 0x8c, 0x88, 0x04, 0x98, 0xcc, 0x5b, 0x89, 0x6f, 0x26, + 0x66, 0x8b, 0xb8, 0x18, 0x17, 0x63, 0x1d, 0xc7, 0xfe, 0xf1, 0x02, 0x1c, 0xc9, 0x70, 0x37, 0xe5, + 0xd7, 0xc8, 0x86, 0x1b, 0x46, 0xc1, 0x4e, 0xf2, 0x72, 0xc2, 0xa2, 0x1c, 0x2b, 0x0c, 0x7a, 0x56, + 0xf1, 0x8b, 0x2a, 0x79, 0x39, 0x09, 0x77, 0x2e, 0x01, 0x3d, 0xd8, 0xe5, 0x44, 0xaf, 0xed, 0x76, + 0x48, 0x64, 0x86, 0x03, 0x75, 0x6d, 0x33, 0xc3, 0x05, 0x06, 0xa1, 0x4f, 0xc0, 0x0d, 0xa5, 0x8d, + 0xd7, 0x9e, 0x80, 0x5c, 0x1f, 0xcf, 0x61, 0xb4, 0x73, 0x11, 0xf1, 0x1c, 0x2f, 0x12, 0x0f, 0xc5, + 0x38, 0xf2, 0x35, 0x2b, 0xc5, 0x02, 0x6a, 0x7f, 0xb9, 0x08, 0x27, 0x73, 0x1d, 0xd0, 0x69, 0xd7, + 0x9b, 0xbe, 0xe7, 0x46, 0xbe, 0x32, 0xf2, 0xe4, 0xd1, 0xae, 0x49, 0x6b, 0x73, 0x45, 0x94, 0x63, + 0x85, 0x81, 0xce, 0x41, 0x3f, 0x93, 0xdb, 0x27, 0x93, 0xdf, 0xe1, 0xf9, 0x45, 0x1e, 0x0b, 0x94, + 0x83, 0xb5, 0x5b, 0xbd, 0xd8, 0xf1, 0x56, 0x7f, 0x8c, 0x72, 0x30, 0x7e, 0x23, 0x79, 0xa1, 0xd0, + 0xee, 0xfa, 0x7e, 0x03, 0x33, 0x20, 0x7a, 0x42, 0x8c, 0x57, 0xc2, 0xaa, 0x11, 0x3b, 0x75, 0x3f, + 0xd4, 0x06, 0xed, 0x29, 0x18, 0xdc, 0x22, 0x3b, 0x81, 0xeb, 0x6d, 0x24, 0xad, 0x5d, 0xaf, 0xf2, + 0x62, 0x2c, 0xe1, 0x66, 0x96, 0xf8, 0xc1, 0x07, 0x91, 0x25, 0x5e, 0x5f, 0x01, 0x43, 0x5d, 0xd9, + 0x93, 0x9f, 0x28, 0xc2, 0x04, 0x9e, 0x5f, 0xfc, 0x60, 0x22, 0x6e, 0xa4, 0x27, 0xe2, 0x41, 0x24, + 0x53, 0x3f, 0xd8, 0x6c, 0xfc, 0x9e, 0x05, 0x13, 0x2c, 0x0d, 0xa7, 0x88, 0x1e, 0xe3, 0xfa, 0xde, + 0x21, 0x3c, 0x05, 0x1e, 0x83, 0xfe, 0x80, 0x36, 0x2a, 0x66, 0x50, 0xed, 0x71, 0xd6, 0x13, 0xcc, + 0x61, 0xe8, 0x14, 0xf4, 0xb1, 0x2e, 0xd0, 0xc9, 0x1b, 0xe5, 0x47, 0xf0, 0xa2, 0x13, 0x39, 0x98, + 0x95, 0xb2, 0x38, 0x96, 0x98, 0xb4, 0x1a, 0x2e, 0xef, 0x74, 0x6c, 0x55, 0xf1, 0xfe, 0x08, 0x4d, + 0x93, 0xd9, 0xb5, 0xf7, 0x16, 0xc7, 0x32, 0x9b, 0x64, 0xe7, 0x67, 0xf6, 0x3f, 0x15, 0xe0, 0x4c, + 0x66, 0xbd, 0x9e, 0xe3, 0x58, 0x76, 0xae, 0xfd, 0x30, 0x93, 0xf6, 0x15, 0x0f, 0xd1, 0x97, 0xa0, + 0xaf, 0x57, 0xee, 0xbf, 0xbf, 0x87, 0xf0, 0x92, 0x99, 0x43, 0xf6, 0x3e, 0x09, 0x2f, 0x99, 0xd9, + 0xb7, 0x1c, 0x31, 0xc1, 0xb7, 0x0b, 0x39, 0xdf, 0xc2, 0x04, 0x06, 0xe7, 0xe9, 0x39, 0xc3, 0x80, + 0xa1, 0x7c, 0x84, 0xf3, 0x33, 0x86, 0x97, 0x61, 0x05, 0x45, 0x73, 0x30, 0xd1, 0x74, 0x3d, 0x7a, + 0xf8, 0xec, 0x98, 0xac, 0xb8, 0x52, 0xb7, 0xac, 0x98, 0x60, 0x9c, 0xc4, 0x47, 0xae, 0x16, 0x7a, + 0x92, 0x7f, 0xdd, 0xab, 0x07, 0xda, 0x75, 0xb3, 0xa6, 0xc5, 0x89, 0x1a, 0xc5, 0x8c, 0x30, 0x94, + 0x2b, 0x9a, 0x9c, 0xa8, 0xd8, 0xbb, 0x9c, 0x68, 0x34, 0x5b, 0x46, 0x34, 0xf3, 0x2a, 0x8c, 0xdd, + 0xb7, 0x9e, 0xc5, 0xfe, 0x66, 0x11, 0x1e, 0xe9, 0xb0, 0xed, 0xf9, 0x59, 0x6f, 0xcc, 0x81, 0x76, + 0xd6, 0xa7, 0xe6, 0xa1, 0x02, 0x47, 0xd7, 0xdb, 0x8d, 0xc6, 0x0e, 0x73, 0xc0, 0x23, 0x75, 0x89, + 0x21, 0x78, 0x4a, 0x29, 0x1c, 0x39, 0xba, 0x9c, 0x81, 0x83, 0x33, 0x6b, 0xd2, 0x27, 0x16, 0xbd, + 0x49, 0x76, 0x14, 0xa9, 0xc4, 0x13, 0x0b, 0xeb, 0x40, 0x6c, 0xe2, 0xa2, 0xcb, 0x30, 0xe5, 0x6c, + 0x3b, 0x2e, 0x4f, 0x7a, 0x22, 0x09, 0xf0, 0x37, 0x96, 0x92, 0x45, 0xcf, 0x25, 0x11, 0x70, 0xba, + 0x4e, 0x8e, 0x4a, 0xa8, 0x78, 0x5f, 0x2a, 0x21, 0x33, 0x08, 0xe2, 0x40, 0x7e, 0x10, 0xc4, 0xce, + 0xe7, 0x62, 0xd7, 0x7c, 0x91, 0xef, 0xc0, 0xd8, 0x41, 0x2d, 0xc7, 0x9f, 0x82, 0xc1, 0x40, 0x64, + 0xe2, 0x4f, 0x78, 0xbb, 0xcb, 0x3c, 0xe5, 0x12, 0x6e, 0xff, 0x6f, 0x16, 0x28, 0x59, 0xb2, 0x19, + 0xef, 0xfc, 0x55, 0x66, 0x06, 0xcf, 0xa5, 0xe0, 0x5a, 0x88, 0xb3, 0x63, 0x9a, 0x19, 0x7c, 0x0c, + 0xc4, 0x26, 0x2e, 0x5f, 0x6e, 0x61, 0x1c, 0x59, 0xc3, 0x78, 0x40, 0x08, 0x0d, 0xa4, 0xc2, 0x40, + 0x9f, 0x80, 0xc1, 0xba, 0xbb, 0xed, 0x86, 0x42, 0x8e, 0x76, 0x60, 0x1d, 0x60, 0xfc, 0x7d, 0x8b, + 0x9c, 0x0c, 0x96, 0xf4, 0xec, 0x9f, 0xb2, 0x40, 0xa9, 0x4e, 0xaf, 0x10, 0xa7, 0x11, 0x6d, 0xa2, + 0x37, 0x00, 0x24, 0x05, 0x25, 0x7b, 0x93, 0x06, 0x5d, 0x80, 0x15, 0x64, 0xdf, 0xf8, 0x87, 0xb5, + 0x3a, 0xe8, 0x75, 0x18, 0xd8, 0x64, 0xb4, 0xc4, 0xb7, 0x9d, 0x53, 0xaa, 0x2e, 0x56, 0xba, 0xbf, + 0x5b, 0x3a, 0x6a, 0xb6, 0x29, 0x6f, 0x31, 0x5e, 0xcb, 0xfe, 0x89, 0x42, 0x3c, 0xa7, 0x6f, 0xb5, + 0xfd, 0xc8, 0x39, 0x04, 0x4e, 0xe4, 0xb2, 0xc1, 0x89, 0x3c, 0xd1, 0x49, 0x37, 0xcc, 0xba, 0x94, + 0xcb, 0x81, 0x5c, 0x4f, 0x70, 0x20, 0x4f, 0x76, 0x27, 0xd5, 0x99, 0xf3, 0xf8, 0x6f, 0x2c, 0x98, + 0x32, 0xf0, 0x0f, 0xe1, 0x02, 0x5c, 0x36, 0x2f, 0xc0, 0x47, 0xbb, 0x7e, 0x43, 0xce, 0xc5, 0xf7, + 0xa3, 0xc5, 0x44, 0xdf, 0xd9, 0x85, 0xf7, 0x2e, 0xf4, 0x6d, 0x3a, 0x41, 0x5d, 0xbc, 0xeb, 0x2f, + 0xf4, 0x34, 0xd6, 0xb3, 0x57, 0x9c, 0x40, 0x18, 0x83, 0x3c, 0x2b, 0x47, 0x9d, 0x16, 0x75, 0x35, + 0x04, 0x61, 0x4d, 0xa1, 0x4b, 0x30, 0x10, 0xd6, 0xfc, 0x96, 0xf2, 0x29, 0x64, 0x49, 0xd4, 0xab, + 0xac, 0x64, 0x7f, 0xb7, 0x84, 0xcc, 0xe6, 0x68, 0x31, 0x16, 0xf8, 0xe8, 0x6d, 0x18, 0x63, 0xbf, + 0x94, 0x65, 0x66, 0x31, 0x5f, 0x02, 0x53, 0xd5, 0x11, 0xb9, 0xd9, 0xb2, 0x51, 0x84, 0x4d, 0x52, + 0x33, 0x1b, 0x30, 0xac, 0x3e, 0xeb, 0xa1, 0x6a, 0xfe, 0xff, 0xba, 0x08, 0x47, 0x32, 0xd6, 0x1c, + 0x0a, 0x8d, 0x99, 0xb8, 0xd8, 0xe3, 0x52, 0x7d, 0x8f, 0x73, 0x11, 0xb2, 0x07, 0x60, 0x5d, 0xac, + 0xad, 0x9e, 0x1b, 0xbd, 0x11, 0x92, 0x64, 0xa3, 0xb4, 0xa8, 0x7b, 0xa3, 0xb4, 0xb1, 0x43, 0x1b, + 0x6a, 0xda, 0x90, 0xea, 0xe9, 0x43, 0x9d, 0xd3, 0x3f, 0xe9, 0x83, 0xa3, 0x59, 0xe6, 0x2a, 0xe8, + 0x73, 0x30, 0xc0, 0x9c, 0xde, 0xa4, 0xe0, 0xec, 0xc5, 0x5e, 0x0d, 0x5d, 0x66, 0x99, 0xdf, 0x9c, + 0x08, 0x99, 0x3b, 0x2b, 0x8f, 0x23, 0x5e, 0xd8, 0x75, 0x98, 0x45, 0x9b, 0x2c, 0x94, 0x95, 0xb8, + 0x3d, 0xe5, 0xf1, 0xf1, 0x91, 0x9e, 0x3b, 0x20, 0xee, 0xdf, 0x30, 0x61, 0xf5, 0x25, 0x8b, 0xbb, + 0x5b, 0x7d, 0xc9, 0x96, 0x51, 0x19, 0x06, 0x6a, 0xdc, 0x9c, 0xa8, 0xd8, 0xfd, 0x08, 0xe3, 0xb6, + 0x44, 0xea, 0x00, 0x16, 0x36, 0x44, 0x82, 0xc0, 0x8c, 0x0b, 0x23, 0xda, 0xc0, 0x3c, 0xd4, 0xc5, + 0xb3, 0x45, 0x2f, 0x3e, 0x6d, 0x08, 0x1e, 0xea, 0x02, 0xfa, 0x59, 0xed, 0xee, 0x17, 0xe7, 0xc1, + 0x87, 0x0d, 0xde, 0xe9, 0x54, 0xc2, 0x15, 0x31, 0xb1, 0xaf, 0x18, 0x2f, 0x55, 0x35, 0x63, 0xcd, + 0xe7, 0x26, 0xcc, 0x32, 0x2f, 0xfc, 0xce, 0xf1, 0xe5, 0xed, 0x9f, 0xb3, 0x20, 0xe1, 0x2c, 0xa6, + 0xc4, 0x9d, 0x56, 0xae, 0xb8, 0xf3, 0x2c, 0xf4, 0x05, 0x7e, 0x43, 0xf2, 0x53, 0x0a, 0x03, 0xfb, + 0x0d, 0x82, 0x19, 0x84, 0x62, 0x44, 0xb1, 0x10, 0x6b, 0x54, 0x7f, 0xa0, 0x8b, 0xa7, 0xf7, 0x63, + 0xd0, 0xdf, 0x20, 0xdb, 0xa4, 0x91, 0xcc, 0x1b, 0x7b, 0x8d, 0x16, 0x62, 0x0e, 0xb3, 0x7f, 0xaf, + 0x0f, 0x4e, 0x77, 0x8c, 0x78, 0x47, 0x19, 0xcc, 0x0d, 0x27, 0x22, 0x77, 0x9c, 0x9d, 0x64, 0xbe, + 0xc4, 0xcb, 0xbc, 0x18, 0x4b, 0x38, 0x73, 0xdc, 0xe6, 0x39, 0x80, 0x12, 0xc2, 0x61, 0x91, 0xfa, + 0x47, 0x40, 0x4d, 0x61, 0x63, 0xf1, 0x41, 0x08, 0x1b, 0x9f, 0x07, 0x08, 0xc3, 0x06, 0xb7, 0x09, + 0xad, 0x0b, 0x8f, 0xf0, 0x38, 0x57, 0x54, 0xf5, 0x9a, 0x80, 0x60, 0x0d, 0x0b, 0x2d, 0xc2, 0x64, + 0x2b, 0xf0, 0x23, 0x2e, 0x6b, 0x5f, 0xe4, 0x66, 0xd3, 0xfd, 0x66, 0xb0, 0xb1, 0x4a, 0x02, 0x8e, + 0x53, 0x35, 0xd0, 0x4b, 0x30, 0x22, 0x02, 0x90, 0x55, 0x7c, 0xbf, 0x21, 0xc4, 0x7b, 0xca, 0x92, + 0xb8, 0x1a, 0x83, 0xb0, 0x8e, 0xa7, 0x55, 0x63, 0x02, 0xfc, 0xc1, 0xcc, 0x6a, 0x5c, 0x88, 0xaf, + 0xe1, 0x25, 0x92, 0x15, 0x0c, 0xf5, 0x94, 0xac, 0x20, 0x16, 0x78, 0x0e, 0xf7, 0xac, 0x4f, 0x86, + 0xae, 0x22, 0xc2, 0xaf, 0xf5, 0xc1, 0x11, 0xb1, 0x70, 0x1e, 0xf6, 0x72, 0xb9, 0x91, 0x5e, 0x2e, + 0x0f, 0x42, 0x24, 0xfa, 0xc1, 0x9a, 0x39, 0xec, 0x35, 0xf3, 0x93, 0x16, 0x98, 0x3c, 0x24, 0xfa, + 0x8f, 0x72, 0x13, 0xce, 0xbe, 0x94, 0xcb, 0x93, 0xc6, 0x91, 0xcc, 0xdf, 0x5b, 0xea, 0x59, 0xfb, + 0x7f, 0xb1, 0xe0, 0xd1, 0xae, 0x14, 0xd1, 0x12, 0x0c, 0x33, 0x46, 0x57, 0x7b, 0x17, 0x3f, 0xa9, + 0xdc, 0x2a, 0x24, 0x20, 0x87, 0xef, 0x8e, 0x6b, 0xa2, 0xa5, 0x54, 0x66, 0xdf, 0xa7, 0x32, 0x32, + 0xfb, 0x1e, 0x33, 0x86, 0xe7, 0x3e, 0x53, 0xfb, 0x7e, 0x89, 0xde, 0x38, 0xa6, 0x6f, 0xe6, 0x47, + 0x0c, 0x71, 0xae, 0x9d, 0x10, 0xe7, 0x22, 0x13, 0x5b, 0xbb, 0x43, 0xde, 0x80, 0x49, 0x16, 0x99, + 0x94, 0x39, 0xf9, 0x08, 0xa7, 0xce, 0x42, 0x6c, 0xc8, 0x7f, 0x2d, 0x01, 0xc3, 0x29, 0x6c, 0xfb, + 0x1f, 0x8a, 0x30, 0xc0, 0xb7, 0xdf, 0x21, 0x3c, 0x7c, 0x9f, 0x81, 0x61, 0xb7, 0xd9, 0x6c, 0xf3, + 0x64, 0xad, 0xfd, 0xb1, 0x59, 0x78, 0x59, 0x16, 0xe2, 0x18, 0x8e, 0x96, 0x85, 0x26, 0xa1, 0x43, + 0xf0, 0x73, 0xde, 0xf1, 0xd9, 0x45, 0x27, 0x72, 0x38, 0x17, 0xa7, 0xee, 0xd9, 0x58, 0xe7, 0x80, + 0x3e, 0x0d, 0x10, 0x46, 0x81, 0xeb, 0x6d, 0xd0, 0x32, 0x91, 0x21, 0xe3, 0xe9, 0x0e, 0xd4, 0xaa, + 0x0a, 0x99, 0xd3, 0x8c, 0xcf, 0x1c, 0x05, 0xc0, 0x1a, 0x45, 0x34, 0x6b, 0xdc, 0xf4, 0x33, 0x89, + 0xb9, 0x03, 0x4e, 0x35, 0x9e, 0xb3, 0x99, 0x97, 0x61, 0x58, 0x11, 0xef, 0x26, 0x57, 0x1c, 0xd5, + 0x19, 0xb6, 0x8f, 0xc1, 0x44, 0xa2, 0x6f, 0x07, 0x12, 0x4b, 0xfe, 0xbe, 0x05, 0x13, 0xbc, 0x33, + 0x4b, 0xde, 0xb6, 0xb8, 0x0d, 0xee, 0xc1, 0xd1, 0x46, 0xc6, 0xa9, 0x2c, 0xa6, 0xbf, 0xf7, 0x53, + 0x5c, 0x89, 0x21, 0xb3, 0xa0, 0x38, 0xb3, 0x0d, 0x74, 0x9e, 0xee, 0x38, 0x7a, 0xea, 0x3a, 0x0d, + 0x11, 0x99, 0x64, 0x94, 0xef, 0x36, 0x5e, 0x86, 0x15, 0xd4, 0xfe, 0x5b, 0x0b, 0xa6, 0x78, 0xcf, + 0xaf, 0x92, 0x1d, 0x75, 0x36, 0x7d, 0x27, 0xfb, 0x2e, 0xd2, 0x84, 0x17, 0x72, 0xd2, 0x84, 0xeb, + 0x9f, 0x56, 0xec, 0xf8, 0x69, 0x5f, 0xb5, 0x40, 0xac, 0x90, 0x43, 0x90, 0xb4, 0x7c, 0x9f, 0x29, + 0x69, 0x99, 0xc9, 0xdf, 0x04, 0x39, 0x22, 0x96, 0x7f, 0xb3, 0x60, 0x92, 0x23, 0xc4, 0x56, 0x10, + 0xdf, 0xd1, 0x79, 0x98, 0x37, 0xbf, 0x28, 0xd3, 0xac, 0xf5, 0x2a, 0xd9, 0x59, 0xf3, 0x2b, 0x4e, + 0xb4, 0x99, 0xfd, 0x51, 0xc6, 0x64, 0xf5, 0x75, 0x9c, 0xac, 0xba, 0xdc, 0x40, 0x46, 0x42, 0xc8, + 0x2e, 0x02, 0xe0, 0x83, 0x26, 0x84, 0xb4, 0xff, 0xd1, 0x02, 0xc4, 0x9b, 0x31, 0x18, 0x37, 0xca, + 0x0e, 0xb1, 0x52, 0xed, 0xa2, 0x8b, 0x8f, 0x26, 0x05, 0xc1, 0x1a, 0xd6, 0x03, 0x19, 0x9e, 0x84, + 0x29, 0x4b, 0xb1, 0xbb, 0x29, 0xcb, 0x01, 0x46, 0xf4, 0xab, 0x83, 0x90, 0x74, 0xeb, 0x44, 0x37, + 0x61, 0xb4, 0xe6, 0xb4, 0x9c, 0xdb, 0x6e, 0xc3, 0x8d, 0x5c, 0x12, 0x76, 0xb2, 0x73, 0x5b, 0xd0, + 0xf0, 0x84, 0xf1, 0x81, 0x56, 0x82, 0x0d, 0x3a, 0x68, 0x16, 0xa0, 0x15, 0xb8, 0xdb, 0x6e, 0x83, + 0x6c, 0x30, 0x81, 0x10, 0x8b, 0x85, 0xc4, 0x8d, 0xee, 0x64, 0x29, 0xd6, 0x30, 0x32, 0x42, 0x90, + 0x14, 0x1f, 0x72, 0x08, 0x12, 0x38, 0xb4, 0x10, 0x24, 0x7d, 0x07, 0x0a, 0x41, 0x32, 0x74, 0xe0, + 0x10, 0x24, 0xfd, 0x3d, 0x85, 0x20, 0xc1, 0x70, 0x5c, 0xf2, 0x9e, 0xf4, 0xff, 0xb2, 0xdb, 0x20, + 0xe2, 0xc1, 0xc1, 0x03, 0x38, 0xcd, 0xec, 0xed, 0x96, 0x8e, 0xe3, 0x4c, 0x0c, 0x9c, 0x53, 0x13, + 0x7d, 0x1c, 0xa6, 0x9d, 0x46, 0xc3, 0xbf, 0xa3, 0x26, 0x75, 0x29, 0xac, 0x39, 0x8d, 0x38, 0xae, + 0xdf, 0xd0, 0xfc, 0xa9, 0xbd, 0xdd, 0xd2, 0xf4, 0x5c, 0x0e, 0x0e, 0xce, 0xad, 0x8d, 0x5e, 0x83, + 0xe1, 0x56, 0xe0, 0xd7, 0x56, 0x34, 0xdf, 0xf3, 0x33, 0x74, 0x00, 0x2b, 0xb2, 0x70, 0x7f, 0xb7, + 0x34, 0xa6, 0xfe, 0xb0, 0x0b, 0x3f, 0xae, 0x90, 0x11, 0xdd, 0x63, 0xe4, 0x61, 0x47, 0xf7, 0x18, + 0x7d, 0xc0, 0xd1, 0x3d, 0xec, 0x2d, 0x38, 0x52, 0x25, 0x81, 0xeb, 0x34, 0xdc, 0x7b, 0x94, 0x27, + 0x97, 0x67, 0xe0, 0x1a, 0x0c, 0x07, 0x89, 0x53, 0xbf, 0xa7, 0xa0, 0xe7, 0x9a, 0x5c, 0x46, 0x9e, + 0xf2, 0x31, 0x21, 0xfb, 0xff, 0xb7, 0x60, 0x50, 0xb8, 0x8a, 0x1e, 0x02, 0x67, 0x3a, 0x67, 0xa8, + 0x64, 0x4a, 0xd9, 0x93, 0xc2, 0x3a, 0x93, 0xab, 0x8c, 0x29, 0x27, 0x94, 0x31, 0x8f, 0x76, 0x22, + 0xd2, 0x59, 0x0d, 0xf3, 0x9f, 0x15, 0xe9, 0x0b, 0xc1, 0x08, 0x5a, 0xf0, 0xf0, 0x87, 0x60, 0x15, + 0x06, 0x43, 0xe1, 0x34, 0x5f, 0xc8, 0xf7, 0xe5, 0x49, 0x4e, 0x62, 0x6c, 0x03, 0x29, 0xdc, 0xe4, + 0x25, 0x91, 0x4c, 0x6f, 0xfc, 0xe2, 0x43, 0xf4, 0xc6, 0xef, 0x16, 0xd6, 0xa1, 0xef, 0x41, 0x84, + 0x75, 0xb0, 0xbf, 0xce, 0x6e, 0x67, 0xbd, 0xfc, 0x10, 0x18, 0xb7, 0xcb, 0xe6, 0x3d, 0x6e, 0x77, + 0x58, 0x59, 0xa2, 0x53, 0x39, 0x0c, 0xdc, 0xef, 0x5a, 0x70, 0x3a, 0xe3, 0xab, 0x34, 0x6e, 0xee, + 0x59, 0x18, 0x72, 0xda, 0x75, 0x57, 0xed, 0x65, 0x4d, 0x5b, 0x3c, 0x27, 0xca, 0xb1, 0xc2, 0x40, + 0x0b, 0x30, 0x45, 0xee, 0xb6, 0x5c, 0xae, 0x86, 0xd7, 0x4d, 0xc7, 0x8b, 0xdc, 0xbf, 0x78, 0x29, + 0x09, 0xc4, 0x69, 0x7c, 0x15, 0x1a, 0xae, 0x98, 0x1b, 0x1a, 0xee, 0x37, 0x2d, 0x18, 0x51, 0x6e, + 0xe3, 0x0f, 0x7d, 0xb4, 0xdf, 0x30, 0x47, 0xfb, 0x91, 0x0e, 0xa3, 0x9d, 0x33, 0xcc, 0x7f, 0x53, + 0x50, 0xfd, 0xad, 0xf8, 0x41, 0xd4, 0x03, 0x97, 0x78, 0xff, 0x6e, 0x2f, 0x17, 0x61, 0xc4, 0x69, + 0xb5, 0x24, 0x40, 0xda, 0x2f, 0xb2, 0x14, 0x16, 0x71, 0x31, 0xd6, 0x71, 0x94, 0x17, 0x4e, 0x31, + 0xd7, 0x0b, 0xa7, 0x0e, 0x10, 0x39, 0xc1, 0x06, 0x89, 0x68, 0x99, 0x30, 0xb7, 0xce, 0x3f, 0x6f, + 0xda, 0x91, 0xdb, 0x98, 0x75, 0xbd, 0x28, 0x8c, 0x82, 0xd9, 0xb2, 0x17, 0x5d, 0x0f, 0xf8, 0x33, + 0x55, 0x0b, 0xc0, 0xa8, 0x68, 0x61, 0x8d, 0xae, 0x0c, 0x91, 0xc2, 0xda, 0xe8, 0x37, 0x0d, 0x61, + 0x56, 0x45, 0x39, 0x56, 0x18, 0xf6, 0xcb, 0xec, 0xf6, 0x61, 0x63, 0x7a, 0xb0, 0xc0, 0x82, 0xff, + 0x34, 0xaa, 0x66, 0x83, 0xa9, 0x84, 0x17, 0xf5, 0xf0, 0x85, 0x9d, 0x0f, 0x7b, 0xda, 0xb0, 0xee, + 0xcf, 0x1a, 0xc7, 0x38, 0x44, 0x9f, 0x4c, 0x19, 0x37, 0x3d, 0xd7, 0xe5, 0xd6, 0x38, 0x80, 0x39, + 0x13, 0xcb, 0x67, 0xc7, 0xb2, 0x7d, 0x95, 0x2b, 0x62, 0x5f, 0x68, 0xf9, 0xec, 0x04, 0x00, 0xc7, + 0x38, 0x94, 0x61, 0x53, 0x7f, 0xc2, 0x69, 0x14, 0x87, 0x3d, 0x57, 0xd8, 0x21, 0xd6, 0x30, 0xd0, + 0x05, 0x21, 0xb4, 0xe0, 0xba, 0x87, 0x47, 0x12, 0x42, 0x0b, 0x39, 0x5c, 0x9a, 0xa4, 0xe9, 0x22, + 0x8c, 0x90, 0xbb, 0x11, 0x09, 0x3c, 0xa7, 0x41, 0x5b, 0xe8, 0x8f, 0xa3, 0xeb, 0x2e, 0xc5, 0xc5, + 0x58, 0xc7, 0x41, 0x6b, 0x30, 0x11, 0x72, 0x59, 0x9e, 0x4a, 0xb6, 0xc1, 0x65, 0xa2, 0x4f, 0x2b, + 0x87, 0x7d, 0x13, 0xbc, 0xcf, 0x8a, 0xf8, 0xe9, 0x24, 0xc3, 0x98, 0x24, 0x49, 0xa0, 0xd7, 0x61, + 0xbc, 0xe1, 0x3b, 0xf5, 0x79, 0xa7, 0xe1, 0x78, 0x35, 0x36, 0x3e, 0x43, 0x46, 0x2c, 0xcb, 0xf1, + 0x6b, 0x06, 0x14, 0x27, 0xb0, 0x29, 0x83, 0xa8, 0x97, 0x88, 0x04, 0x31, 0x8e, 0xb7, 0x41, 0xc2, + 0xe9, 0x61, 0xf6, 0x55, 0x8c, 0x41, 0xbc, 0x96, 0x83, 0x83, 0x73, 0x6b, 0xa3, 0x4b, 0x30, 0x2a, + 0x3f, 0x5f, 0x8b, 0xfa, 0x13, 0x3b, 0x34, 0x69, 0x30, 0x6c, 0x60, 0xa2, 0x10, 0x8e, 0xc9, 0xff, + 0x6b, 0x81, 0xb3, 0xbe, 0xee, 0xd6, 0x44, 0x28, 0x0c, 0xee, 0xfc, 0xfd, 0x31, 0xe9, 0x69, 0xba, + 0x94, 0x85, 0xb4, 0xbf, 0x5b, 0x3a, 0x25, 0x46, 0x2d, 0x13, 0x8e, 0xb3, 0x69, 0xa3, 0x15, 0x38, + 0xc2, 0x6d, 0x60, 0x16, 0x36, 0x49, 0x6d, 0x4b, 0x6e, 0x38, 0xc6, 0x35, 0x6a, 0x8e, 0x3f, 0x57, + 0xd2, 0x28, 0x38, 0xab, 0x1e, 0x7a, 0x07, 0xa6, 0x5b, 0xed, 0xdb, 0x0d, 0x37, 0xdc, 0x5c, 0xf5, + 0x23, 0x66, 0x42, 0x36, 0x57, 0xaf, 0x07, 0x24, 0xe4, 0xbe, 0xc1, 0xec, 0xea, 0x95, 0x91, 0x9a, + 0x2a, 0x39, 0x78, 0x38, 0x97, 0x02, 0xba, 0x07, 0xc7, 0x12, 0x0b, 0x41, 0x84, 0x5c, 0x19, 0xcf, + 0x4f, 0xb5, 0x55, 0xcd, 0xaa, 0x20, 0xa2, 0x17, 0x65, 0x81, 0x70, 0x76, 0x13, 0xe8, 0x15, 0x00, + 0xb7, 0xb5, 0xec, 0x34, 0xdd, 0x06, 0x7d, 0x8e, 0x1e, 0x61, 0x6b, 0x84, 0x3e, 0x4d, 0xa0, 0x5c, + 0x91, 0xa5, 0xf4, 0x6c, 0x16, 0xff, 0x76, 0xb0, 0x86, 0x8d, 0xae, 0xc1, 0xb8, 0xf8, 0xb7, 0x23, + 0xa6, 0x74, 0x4a, 0x65, 0x65, 0x1d, 0x97, 0x35, 0xd4, 0x3c, 0x26, 0x4a, 0x70, 0xa2, 0x2e, 0xda, + 0x80, 0xd3, 0x32, 0x25, 0xac, 0xbe, 0x3e, 0xe5, 0x1c, 0x84, 0x2c, 0xbf, 0xd5, 0x10, 0xf7, 0x29, + 0x9a, 0xeb, 0x84, 0x88, 0x3b, 0xd3, 0xa1, 0xf7, 0xba, 0xbe, 0xcc, 0xb9, 0xc7, 0xf8, 0xb1, 0x38, + 0x22, 0xe8, 0xb5, 0x24, 0x10, 0xa7, 0xf1, 0x91, 0x0f, 0xc7, 0x5c, 0x2f, 0x6b, 0x55, 0x1f, 0x67, + 0x84, 0x3e, 0xca, 0x9d, 0xe5, 0x3b, 0xaf, 0xe8, 0x4c, 0x38, 0xce, 0xa6, 0x8b, 0xca, 0x70, 0x24, + 0xe2, 0x05, 0x8b, 0x6e, 0xc8, 0xd3, 0xe7, 0xd0, 0x67, 0xdf, 0x09, 0xd6, 0xdc, 0x09, 0xba, 0x9a, + 0xd7, 0xd2, 0x60, 0x9c, 0x55, 0xe7, 0xbd, 0x19, 0x80, 0x7e, 0xc3, 0xa2, 0xb5, 0x35, 0x46, 0x1f, + 0x7d, 0x06, 0x46, 0xf5, 0xf1, 0x11, 0x4c, 0xcb, 0xb9, 0x6c, 0x3e, 0x58, 0x3b, 0x5e, 0xf8, 0x33, + 0x41, 0x1d, 0x21, 0x3a, 0x0c, 0x1b, 0x14, 0x51, 0x2d, 0x23, 0xc8, 0xc5, 0x85, 0xde, 0x98, 0xa2, + 0xde, 0xed, 0x1f, 0x09, 0x64, 0xef, 0x1c, 0x74, 0x0d, 0x86, 0x6a, 0x0d, 0x97, 0x78, 0x51, 0xb9, + 0xd2, 0x29, 0x50, 0xeb, 0x82, 0xc0, 0x11, 0x5b, 0x51, 0x64, 0xbd, 0xe2, 0x65, 0x58, 0x51, 0xb0, + 0x2f, 0xc1, 0x48, 0xb5, 0x41, 0x48, 0x8b, 0xfb, 0x71, 0xa1, 0xa7, 0xd8, 0xc3, 0x84, 0xb1, 0x96, + 0x16, 0x63, 0x2d, 0xf5, 0x37, 0x07, 0x63, 0x2a, 0x25, 0xdc, 0xfe, 0xb3, 0x02, 0x94, 0xba, 0x24, + 0x5f, 0x4b, 0xe8, 0xdb, 0xac, 0x9e, 0xf4, 0x6d, 0x73, 0x30, 0x11, 0xff, 0xd3, 0x45, 0x79, 0xca, + 0x18, 0xfa, 0xa6, 0x09, 0xc6, 0x49, 0xfc, 0x9e, 0xfd, 0x5a, 0x74, 0x95, 0x5d, 0x5f, 0x57, 0xcf, + 0x2c, 0x43, 0x55, 0xdf, 0xdf, 0xfb, 0xdb, 0x3b, 0x57, 0xed, 0x6a, 0x7f, 0xbd, 0x00, 0xc7, 0xd4, + 0x10, 0x7e, 0xef, 0x0e, 0xdc, 0x8d, 0xf4, 0xc0, 0x3d, 0x00, 0xa5, 0xb5, 0x7d, 0x1d, 0x06, 0x78, + 0xf4, 0xd8, 0x1e, 0x78, 0xfe, 0xc7, 0xcc, 0x40, 0xfe, 0x8a, 0xcd, 0x34, 0x82, 0xf9, 0xff, 0x98, + 0x05, 0x13, 0x09, 0x07, 0x49, 0x84, 0x35, 0x2f, 0xfa, 0xfb, 0xe1, 0xcb, 0xb3, 0x38, 0xfe, 0xb3, + 0xd0, 0xb7, 0xe9, 0x2b, 0x23, 0x65, 0x85, 0x71, 0xc5, 0x0f, 0x23, 0xcc, 0x20, 0xf6, 0xdf, 0x59, + 0xd0, 0xbf, 0xe6, 0xb8, 0x5e, 0x24, 0xb5, 0x1f, 0x56, 0x8e, 0xf6, 0xa3, 0x97, 0xef, 0x42, 0x2f, + 0xc1, 0x00, 0x59, 0x5f, 0x27, 0xb5, 0x48, 0xcc, 0xaa, 0x8c, 0xa6, 0x31, 0xb0, 0xc4, 0x4a, 0x29, + 0x13, 0xca, 0x1a, 0xe3, 0x7f, 0xb1, 0x40, 0x46, 0xb7, 0x60, 0x38, 0x72, 0x9b, 0x64, 0xae, 0x5e, + 0x17, 0x36, 0x01, 0xf7, 0x11, 0x02, 0x66, 0x4d, 0x12, 0xc0, 0x31, 0x2d, 0xfb, 0xcb, 0x05, 0x80, + 0x38, 0x5a, 0x5d, 0xb7, 0x4f, 0x9c, 0x4f, 0x69, 0x8b, 0xcf, 0x65, 0x68, 0x8b, 0x51, 0x4c, 0x30, + 0x43, 0x55, 0xac, 0x86, 0xa9, 0xd8, 0xd3, 0x30, 0xf5, 0x1d, 0x64, 0x98, 0x16, 0x60, 0x2a, 0x8e, + 0xb6, 0x67, 0x06, 0x1b, 0x65, 0xf7, 0xf7, 0x5a, 0x12, 0x88, 0xd3, 0xf8, 0x36, 0x81, 0xb3, 0x2a, + 0xe8, 0x98, 0xb8, 0x0b, 0x99, 0x2b, 0x81, 0xae, 0x7d, 0xef, 0x32, 0x4e, 0xb1, 0x3a, 0xbc, 0x90, + 0xab, 0x0e, 0xff, 0x45, 0x0b, 0x8e, 0x26, 0xdb, 0x61, 0x7e, 0xf7, 0x5f, 0xb4, 0xe0, 0x58, 0x9c, + 0x7b, 0x28, 0x6d, 0x82, 0xf0, 0x62, 0xc7, 0x40, 0x6a, 0x39, 0x3d, 0x8e, 0xc3, 0xb6, 0xac, 0x64, + 0x91, 0xc6, 0xd9, 0x2d, 0xda, 0xff, 0x5f, 0x1f, 0x4c, 0xe7, 0x45, 0x60, 0x63, 0x9e, 0x46, 0xce, + 0xdd, 0xea, 0x16, 0xb9, 0x23, 0xfc, 0x39, 0x62, 0x4f, 0x23, 0x5e, 0x8c, 0x25, 0x3c, 0x99, 0x6e, + 0xaa, 0xd0, 0x63, 0xba, 0xa9, 0x4d, 0x98, 0xba, 0xb3, 0x49, 0xbc, 0x1b, 0x5e, 0xe8, 0x44, 0x6e, + 0xb8, 0xee, 0x32, 0x05, 0x3a, 0x5f, 0x37, 0xaf, 0x48, 0xaf, 0x8b, 0x5b, 0x49, 0x84, 0xfd, 0xdd, + 0xd2, 0x69, 0xa3, 0x20, 0xee, 0x32, 0x3f, 0x48, 0x70, 0x9a, 0x68, 0x3a, 0x5b, 0x57, 0xdf, 0x43, + 0xce, 0xd6, 0xd5, 0x74, 0x85, 0xd9, 0x8d, 0x74, 0x23, 0x61, 0xcf, 0xd6, 0x15, 0x55, 0x8a, 0x35, + 0x0c, 0xf4, 0x29, 0x40, 0x7a, 0xba, 0x45, 0x23, 0x00, 0xee, 0x73, 0x7b, 0xbb, 0x25, 0xb4, 0x9a, + 0x82, 0xee, 0xef, 0x96, 0x8e, 0xd0, 0xd2, 0xb2, 0x47, 0x9f, 0xbf, 0x71, 0xd4, 0xc0, 0x0c, 0x42, + 0xe8, 0x16, 0x4c, 0xd2, 0x52, 0xb6, 0xa3, 0x64, 0x74, 0x5d, 0xfe, 0x64, 0x7d, 0x66, 0x6f, 0xb7, + 0x34, 0xb9, 0x9a, 0x80, 0xe5, 0x91, 0x4e, 0x11, 0xc9, 0x48, 0xda, 0x35, 0xd4, 0x6b, 0xd2, 0x2e, + 0xfb, 0x8b, 0x16, 0x9c, 0xa4, 0x17, 0x5c, 0xfd, 0x5a, 0x8e, 0x16, 0xdd, 0x69, 0xb9, 0x5c, 0x4f, + 0x23, 0xae, 0x1a, 0x26, 0xab, 0xab, 0x94, 0xb9, 0x96, 0x46, 0x41, 0xe9, 0x09, 0xbf, 0xe5, 0x7a, + 0xf5, 0xe4, 0x09, 0x7f, 0xd5, 0xf5, 0xea, 0x98, 0x41, 0xd4, 0x95, 0x55, 0xcc, 0x8d, 0xd6, 0xff, + 0x35, 0xba, 0x57, 0x69, 0x5f, 0xbe, 0xa3, 0xdd, 0x40, 0xcf, 0xe8, 0x3a, 0x55, 0x61, 0x3e, 0x99, + 0xab, 0x4f, 0xfd, 0x82, 0x05, 0xc2, 0xfb, 0xbd, 0x87, 0x3b, 0xf9, 0x6d, 0x18, 0xdd, 0x4e, 0xa7, + 0xa2, 0x3d, 0x9b, 0x1f, 0x0e, 0x40, 0x24, 0xa0, 0x55, 0x2c, 0xba, 0x91, 0x76, 0xd6, 0xa0, 0x65, + 0xd7, 0x41, 0x40, 0x17, 0x09, 0xd3, 0x6a, 0x74, 0xef, 0xcd, 0xf3, 0x00, 0x75, 0x86, 0xcb, 0xf2, + 0xd3, 0x17, 0x4c, 0x8e, 0x6b, 0x51, 0x41, 0xb0, 0x86, 0x65, 0xff, 0x7a, 0x11, 0x46, 0x64, 0xea, + 0xd3, 0xb6, 0xd7, 0x8b, 0xec, 0x51, 0x67, 0x9c, 0x0a, 0x5d, 0x19, 0xa7, 0x77, 0x60, 0x2a, 0x20, + 0xb5, 0x76, 0x10, 0xba, 0xdb, 0x44, 0x82, 0xc5, 0x26, 0x99, 0xe5, 0xc9, 0x22, 0x12, 0xc0, 0x7d, + 0x16, 0x22, 0x2b, 0x51, 0xc8, 0x94, 0xc6, 0x69, 0x42, 0xe8, 0x02, 0x0c, 0x33, 0xd1, 0x7b, 0x25, + 0x16, 0x08, 0x2b, 0xc1, 0xd7, 0x8a, 0x04, 0xe0, 0x18, 0x87, 0x3d, 0x0e, 0xda, 0xb7, 0x19, 0x7a, + 0xc2, 0x13, 0xbc, 0xca, 0x8b, 0xb1, 0x84, 0xa3, 0x8f, 0xc3, 0x24, 0xaf, 0x17, 0xf8, 0x2d, 0x67, + 0x83, 0xab, 0x04, 0xfb, 0x55, 0x78, 0x9d, 0xc9, 0x95, 0x04, 0x6c, 0x7f, 0xb7, 0x74, 0x34, 0x59, + 0xc6, 0xba, 0x9d, 0xa2, 0xc2, 0x2c, 0xff, 0x78, 0x23, 0xf4, 0xce, 0x48, 0x19, 0x0c, 0xc6, 0x20, + 0xac, 0xe3, 0xd9, 0xff, 0x6a, 0xc1, 0x94, 0x36, 0x55, 0x3d, 0xe7, 0xeb, 0x30, 0x06, 0xa9, 0xd0, + 0xc3, 0x20, 0x1d, 0x2c, 0xda, 0x43, 0xe6, 0x0c, 0xf7, 0x3d, 0xa0, 0x19, 0xb6, 0x3f, 0x03, 0x28, + 0x9d, 0x57, 0x17, 0xbd, 0xc9, 0x0d, 0xf9, 0xdd, 0x80, 0xd4, 0x3b, 0x29, 0xfc, 0xf5, 0xc8, 0x39, + 0xd2, 0x73, 0x95, 0xd7, 0xc2, 0xaa, 0xbe, 0xfd, 0xe3, 0x7d, 0x30, 0x99, 0x8c, 0xd5, 0x81, 0xae, + 0xc0, 0x00, 0xe7, 0xd2, 0x05, 0xf9, 0x0e, 0xf6, 0x64, 0x5a, 0x84, 0x0f, 0x9e, 0x4b, 0x87, 0x73, + 0xf7, 0xa2, 0x3e, 0x7a, 0x07, 0x46, 0xea, 0xfe, 0x1d, 0xef, 0x8e, 0x13, 0xd4, 0xe7, 0x2a, 0x65, + 0x71, 0x42, 0x64, 0x0a, 0xa0, 0x16, 0x63, 0x34, 0x3d, 0x6a, 0x08, 0xb3, 0x9d, 0x88, 0x41, 0x58, + 0x27, 0x87, 0xd6, 0x58, 0x7a, 0xa7, 0x75, 0x77, 0x63, 0xc5, 0x69, 0x75, 0xf2, 0xea, 0x5a, 0x90, + 0x48, 0x1a, 0xe5, 0x31, 0x91, 0x03, 0x8a, 0x03, 0x70, 0x4c, 0x08, 0x7d, 0x0e, 0x8e, 0x84, 0x39, + 0x2a, 0xb1, 0xbc, 0x34, 0xeb, 0x9d, 0xb4, 0x44, 0x5c, 0x98, 0x92, 0xa5, 0x3c, 0xcb, 0x6a, 0x06, + 0xdd, 0x05, 0x24, 0x44, 0xcf, 0x6b, 0x41, 0x3b, 0x8c, 0xe6, 0xdb, 0x5e, 0xbd, 0x21, 0xd3, 0x3f, + 0x7d, 0x38, 0x5b, 0x4e, 0x90, 0xc4, 0xd6, 0xda, 0x66, 0xe1, 0x85, 0xd3, 0x18, 0x38, 0xa3, 0x0d, + 0xfb, 0x0b, 0x7d, 0x30, 0x23, 0x13, 0x59, 0x67, 0x78, 0xaf, 0x7c, 0xde, 0x4a, 0xb8, 0xaf, 0xbc, + 0x92, 0x7f, 0xd0, 0x3f, 0x34, 0x27, 0x96, 0x2f, 0xa5, 0x9d, 0x58, 0x5e, 0x3b, 0x60, 0x37, 0x1e, + 0x98, 0x2b, 0xcb, 0xf7, 0xac, 0xff, 0xc9, 0xde, 0x51, 0x30, 0xae, 0x66, 0x84, 0x79, 0xec, 0xf6, + 0x8a, 0x54, 0x1d, 0xe5, 0x3c, 0xff, 0xaf, 0x08, 0x1c, 0xe3, 0xb2, 0x1f, 0x95, 0x11, 0xde, 0xd9, + 0x39, 0xab, 0xe8, 0x50, 0x9a, 0xa4, 0xd9, 0x8a, 0x76, 0x16, 0xdd, 0x40, 0xf4, 0x38, 0x93, 0xe6, + 0x92, 0xc0, 0x49, 0xd3, 0x94, 0x10, 0xac, 0xe8, 0xa0, 0x6d, 0x98, 0xda, 0x60, 0x11, 0x9f, 0xb4, + 0x9c, 0xd2, 0xe2, 0x5c, 0xc8, 0xdc, 0xb7, 0x97, 0x17, 0x96, 0xf2, 0x13, 0x50, 0xf3, 0xc7, 0x5f, + 0x0a, 0x05, 0xa7, 0x9b, 0xa0, 0x5b, 0xe3, 0xa8, 0x73, 0x27, 0x5c, 0x6a, 0x38, 0x61, 0xe4, 0xd6, + 0xe6, 0x1b, 0x7e, 0x6d, 0xab, 0x1a, 0xf9, 0x81, 0x4c, 0x16, 0x99, 0xf9, 0xf6, 0x9a, 0xbb, 0x55, + 0x4d, 0xe1, 0x1b, 0xcd, 0x4f, 0xef, 0xed, 0x96, 0x8e, 0x66, 0x61, 0xe1, 0xcc, 0xb6, 0xd0, 0x2a, + 0x0c, 0x6e, 0xb8, 0x11, 0x26, 0x2d, 0x5f, 0x9c, 0x16, 0x99, 0x47, 0xe1, 0x65, 0x8e, 0x62, 0xb4, + 0xc4, 0x22, 0x52, 0x09, 0x00, 0x96, 0x44, 0xd0, 0x9b, 0xea, 0x12, 0x18, 0xc8, 0x17, 0xc0, 0xa6, + 0x6d, 0xef, 0x32, 0xaf, 0x81, 0xd7, 0xa1, 0xe8, 0xad, 0x87, 0x9d, 0x62, 0xf1, 0xac, 0x2e, 0x1b, + 0xf2, 0xb3, 0xf9, 0x41, 0xfa, 0x34, 0x5e, 0x5d, 0xae, 0x62, 0x5a, 0x91, 0xb9, 0xbd, 0x86, 0xb5, + 0xd0, 0x15, 0x89, 0xa7, 0x32, 0xbd, 0x80, 0xcb, 0xd5, 0x85, 0x6a, 0xd9, 0xa0, 0xc1, 0xa2, 0x1a, + 0xb2, 0x62, 0xcc, 0xab, 0xa3, 0x9b, 0x30, 0xbc, 0xc1, 0x0f, 0xbe, 0xf5, 0x50, 0x24, 0xb3, 0xcf, + 0xbc, 0x8c, 0x2e, 0x4b, 0x24, 0x83, 0x1e, 0xbb, 0x32, 0x14, 0x08, 0xc7, 0xa4, 0xd0, 0x17, 0x2c, + 0x38, 0xd6, 0x4a, 0x48, 0x50, 0x99, 0xb3, 0x9a, 0x30, 0x53, 0xcb, 0x74, 0x00, 0xa8, 0x64, 0x55, + 0x30, 0x1a, 0x64, 0xea, 0x97, 0x4c, 0x34, 0x9c, 0xdd, 0x1c, 0x1d, 0xe8, 0xe0, 0x76, 0xbd, 0x53, + 0xae, 0xa2, 0x44, 0x60, 0x22, 0x3e, 0xd0, 0x78, 0x7e, 0x11, 0xd3, 0x8a, 0x68, 0x0d, 0x60, 0xbd, + 0x41, 0x44, 0xc4, 0x47, 0x61, 0x14, 0x95, 0x79, 0xfb, 0x2f, 0x2b, 0x2c, 0x41, 0x87, 0xbd, 0x44, + 0xe3, 0x52, 0xac, 0xd1, 0xa1, 0x4b, 0xa9, 0xe6, 0x7a, 0x75, 0x12, 0x30, 0xe5, 0x56, 0xce, 0x52, + 0x5a, 0x60, 0x18, 0xe9, 0xa5, 0xc4, 0xcb, 0xb1, 0xa0, 0xc0, 0x68, 0x91, 0xd6, 0xe6, 0x7a, 0xd8, + 0x29, 0x2b, 0xc6, 0x02, 0x69, 0x6d, 0x26, 0x16, 0x14, 0xa7, 0xc5, 0xca, 0xb1, 0xa0, 0x40, 0xb7, + 0xcc, 0x3a, 0xdd, 0x40, 0x24, 0x98, 0x9e, 0xc8, 0xdf, 0x32, 0xcb, 0x1c, 0x25, 0xbd, 0x65, 0x04, + 0x00, 0x4b, 0x22, 0xe8, 0xd3, 0x26, 0xb7, 0x33, 0xc9, 0x68, 0x3e, 0xd3, 0x85, 0xdb, 0x31, 0xe8, + 0x76, 0xe6, 0x77, 0x5e, 0x81, 0xc2, 0x7a, 0x8d, 0x29, 0xc5, 0x72, 0x74, 0x06, 0xcb, 0x0b, 0x06, + 0x35, 0x16, 0x65, 0x7e, 0x79, 0x01, 0x17, 0xd6, 0x6b, 0x74, 0xe9, 0x3b, 0xf7, 0xda, 0x01, 0x59, + 0x76, 0x1b, 0x44, 0x64, 0xc8, 0xc8, 0x5c, 0xfa, 0x73, 0x12, 0x29, 0xbd, 0xf4, 0x15, 0x08, 0xc7, + 0xa4, 0x28, 0xdd, 0x98, 0x07, 0x3b, 0x92, 0x4f, 0x57, 0xb1, 0x5a, 0x69, 0xba, 0x99, 0x5c, 0xd8, + 0x16, 0x8c, 0x6d, 0x87, 0xad, 0x4d, 0x22, 0x4f, 0x45, 0xa6, 0xae, 0xcb, 0x89, 0x54, 0x71, 0x53, + 0x20, 0xba, 0x41, 0xd4, 0x76, 0x1a, 0xa9, 0x83, 0x9c, 0x89, 0x56, 0x6e, 0xea, 0xc4, 0xb0, 0x49, + 0x9b, 0x2e, 0x84, 0x77, 0x79, 0x38, 0x39, 0xa6, 0xb8, 0xcb, 0x59, 0x08, 0x19, 0x11, 0xe7, 0xf8, + 0x42, 0x10, 0x00, 0x2c, 0x89, 0xa8, 0xc1, 0x66, 0x17, 0xd0, 0xf1, 0x2e, 0x83, 0x9d, 0xea, 0x6f, + 0x3c, 0xd8, 0xec, 0xc2, 0x89, 0x49, 0xb1, 0x8b, 0xa6, 0xb5, 0xe9, 0x47, 0xbe, 0x97, 0xb8, 0xe4, + 0x4e, 0xe4, 0x5f, 0x34, 0x95, 0x0c, 0xfc, 0xf4, 0x45, 0x93, 0x85, 0x85, 0x33, 0xdb, 0xa2, 0x1f, + 0xd7, 0x92, 0x91, 0x01, 0x45, 0x16, 0x8f, 0xa7, 0x72, 0x02, 0x6b, 0xa6, 0xc3, 0x07, 0xf2, 0x8f, + 0x53, 0x20, 0x1c, 0x93, 0x42, 0x75, 0x18, 0x6f, 0x19, 0x11, 0x67, 0x59, 0x36, 0x92, 0x1c, 0xbe, + 0x20, 0x2b, 0x36, 0x2d, 0x97, 0x10, 0x99, 0x10, 0x9c, 0xa0, 0xc9, 0x2c, 0xf7, 0xb8, 0xab, 0x1f, + 0x4b, 0x56, 0x92, 0x33, 0xd5, 0x19, 0xde, 0x80, 0x7c, 0xaa, 0x05, 0x00, 0x4b, 0x22, 0x74, 0x34, + 0x84, 0x83, 0x9a, 0x1f, 0xb2, 0x9c, 0x3f, 0x79, 0x0a, 0xf6, 0x2c, 0x35, 0x91, 0x0c, 0xb3, 0x2e, + 0x40, 0x38, 0x26, 0x45, 0x4f, 0x72, 0x7a, 0xe1, 0x9d, 0xca, 0x3f, 0xc9, 0x93, 0xd7, 0x1d, 0x3b, + 0xc9, 0xe9, 0x65, 0x57, 0x14, 0x57, 0x9d, 0x8a, 0x0a, 0xce, 0xf2, 0x95, 0xe4, 0xf4, 0x4b, 0x85, + 0x15, 0x4f, 0xf7, 0x4b, 0x81, 0x70, 0x4c, 0x8a, 0x5d, 0xc5, 0x2c, 0x34, 0xdd, 0x99, 0x0e, 0x57, + 0x31, 0x45, 0xc8, 0xb8, 0x8a, 0xb5, 0xd0, 0x75, 0xf6, 0x8f, 0x17, 0xe0, 0x4c, 0xe7, 0x7d, 0x1b, + 0xeb, 0xd0, 0x2a, 0xb1, 0xcd, 0x52, 0x42, 0x87, 0xc6, 0x25, 0x3a, 0x31, 0x56, 0xcf, 0x01, 0x87, + 0x2f, 0xc3, 0x94, 0x72, 0x47, 0x6c, 0xb8, 0xb5, 0x1d, 0x2d, 0x49, 0xa9, 0x0a, 0xcd, 0x53, 0x4d, + 0x22, 0xe0, 0x74, 0x1d, 0x34, 0x07, 0x13, 0x46, 0x61, 0x79, 0x51, 0x3c, 0xff, 0xe3, 0x4c, 0x1b, + 0x26, 0x18, 0x27, 0xf1, 0xed, 0xdf, 0xb0, 0xe0, 0x44, 0x4e, 0xfe, 0xfb, 0x9e, 0xe3, 0xe9, 0xae, + 0xc3, 0x44, 0xcb, 0xac, 0xda, 0x25, 0x04, 0xb8, 0x91, 0x65, 0x5f, 0xf5, 0x35, 0x01, 0xc0, 0x49, + 0xa2, 0xf6, 0xaf, 0x15, 0xe0, 0x74, 0x47, 0xfb, 0x7a, 0x84, 0xe1, 0xf8, 0x46, 0x33, 0x74, 0x16, + 0x02, 0x52, 0x27, 0x5e, 0xe4, 0x3a, 0x8d, 0x6a, 0x8b, 0xd4, 0x34, 0x2d, 0x28, 0x33, 0x54, 0xbf, + 0xbc, 0x52, 0x9d, 0x4b, 0x63, 0xe0, 0x9c, 0x9a, 0x68, 0x19, 0x50, 0x1a, 0x22, 0x66, 0x98, 0x3d, + 0x71, 0xd3, 0xf4, 0x70, 0x46, 0x0d, 0xf4, 0x32, 0x8c, 0x29, 0xbb, 0x7d, 0x6d, 0xc6, 0xd9, 0x05, + 0x81, 0x75, 0x00, 0x36, 0xf1, 0xd0, 0x45, 0x9e, 0x82, 0x49, 0x24, 0xeb, 0x12, 0x2a, 0xd3, 0x09, + 0x99, 0x5f, 0x49, 0x14, 0x63, 0x1d, 0x67, 0xfe, 0xd2, 0x5f, 0x7c, 0xeb, 0xcc, 0x87, 0xfe, 0xea, + 0x5b, 0x67, 0x3e, 0xf4, 0xb7, 0xdf, 0x3a, 0xf3, 0xa1, 0x1f, 0xda, 0x3b, 0x63, 0xfd, 0xc5, 0xde, + 0x19, 0xeb, 0xaf, 0xf6, 0xce, 0x58, 0x7f, 0xbb, 0x77, 0xc6, 0xfa, 0xdf, 0xf7, 0xce, 0x58, 0x5f, + 0xfe, 0x3f, 0xce, 0x7c, 0xe8, 0x6d, 0x14, 0x47, 0xa8, 0xbe, 0x40, 0x67, 0xe7, 0xc2, 0xf6, 0xc5, + 0xff, 0x10, 0x00, 0x00, 0xff, 0xff, 0xf5, 0xf1, 0x8c, 0x4c, 0x2d, 0x26, 0x01, 0x00, } func (m *AWSElasticBlockStoreVolumeSource) Marshal() (dAtA []byte, err error) { @@ -9887,6 +9921,13 @@ func (m *ContainerStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.StopSignal != nil { + i -= len(*m.StopSignal) + copy(dAtA[i:], *m.StopSignal) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.StopSignal))) + i-- + dAtA[i] = 0x7a + } if len(m.AllocatedResourcesStatus) > 0 { for iNdEx := len(m.AllocatedResourcesStatus) - 1; iNdEx >= 0; iNdEx-- { { @@ -12258,6 +12299,13 @@ func (m *Lifecycle) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.StopSignal != nil { + i -= len(*m.StopSignal) + copy(dAtA[i:], *m.StopSignal) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.StopSignal))) + i-- + dAtA[i] = 0x1a + } if m.PreStop != nil { { size, err := m.PreStop.MarshalToSizedBuffer(dAtA[:i]) @@ -14135,6 +14183,34 @@ func (m *NodeStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *NodeSwapStatus) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *NodeSwapStatus) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *NodeSwapStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Capacity != nil { + i = encodeVarintGenerated(dAtA, i, uint64(*m.Capacity)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + func (m *NodeSystemInfo) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -14155,6 +14231,18 @@ func (m *NodeSystemInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.Swap != nil { + { + size, err := m.Swap.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x5a + } i -= len(m.Architecture) copy(dAtA[i:], m.Architecture) i = encodeVarintGenerated(dAtA, i, uint64(len(m.Architecture))) @@ -15723,6 +15811,9 @@ func (m *PodCondition) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + i = encodeVarintGenerated(dAtA, i, uint64(m.ObservedGeneration)) + i-- + dAtA[i] = 0x38 i -= len(m.Message) copy(dAtA[i:], m.Message) i = encodeVarintGenerated(dAtA, i, uint64(len(m.Message))) @@ -16994,6 +17085,11 @@ func (m *PodStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + i = encodeVarintGenerated(dAtA, i, uint64(m.ObservedGeneration)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x88 if len(m.HostIPs) > 0 { for iNdEx := len(m.HostIPs) - 1; iNdEx >= 0; iNdEx-- { { @@ -22542,6 +22638,10 @@ func (m *ContainerStatus) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) } } + if m.StopSignal != nil { + l = len(*m.StopSignal) + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -23382,6 +23482,10 @@ func (m *Lifecycle) Size() (n int) { l = m.PreStop.Size() n += 1 + l + sovGenerated(uint64(l)) } + if m.StopSignal != nil { + l = len(*m.StopSignal) + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -24067,6 +24171,18 @@ func (m *NodeStatus) Size() (n int) { return n } +func (m *NodeSwapStatus) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Capacity != nil { + n += 1 + sovGenerated(uint64(*m.Capacity)) + } + return n +} + func (m *NodeSystemInfo) Size() (n int) { if m == nil { return 0 @@ -24093,6 +24209,10 @@ func (m *NodeSystemInfo) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) l = len(m.Architecture) n += 1 + l + sovGenerated(uint64(l)) + if m.Swap != nil { + l = m.Swap.Size() + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -24650,6 +24770,7 @@ func (m *PodCondition) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) l = len(m.Message) n += 1 + l + sovGenerated(uint64(l)) + n += 1 + sovGenerated(uint64(m.ObservedGeneration)) return n } @@ -25174,6 +25295,7 @@ func (m *PodStatus) Size() (n int) { n += 2 + l + sovGenerated(uint64(l)) } } + n += 2 + sovGenerated(uint64(m.ObservedGeneration)) return n } @@ -27457,6 +27579,7 @@ func (this *ContainerStatus) String() string { `VolumeMounts:` + repeatedStringForVolumeMounts + `,`, `User:` + strings.Replace(this.User.String(), "ContainerUser", "ContainerUser", 1) + `,`, `AllocatedResourcesStatus:` + repeatedStringForAllocatedResourcesStatus + `,`, + `StopSignal:` + valueToStringGenerated(this.StopSignal) + `,`, `}`, }, "") return s @@ -28080,6 +28203,7 @@ func (this *Lifecycle) String() string { s := strings.Join([]string{`&Lifecycle{`, `PostStart:` + strings.Replace(this.PostStart.String(), "LifecycleHandler", "LifecycleHandler", 1) + `,`, `PreStop:` + strings.Replace(this.PreStop.String(), "LifecycleHandler", "LifecycleHandler", 1) + `,`, + `StopSignal:` + valueToStringGenerated(this.StopSignal) + `,`, `}`, }, "") return s @@ -28658,6 +28782,16 @@ func (this *NodeStatus) String() string { }, "") return s } +func (this *NodeSwapStatus) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&NodeSwapStatus{`, + `Capacity:` + valueToStringGenerated(this.Capacity) + `,`, + `}`, + }, "") + return s +} func (this *NodeSystemInfo) String() string { if this == nil { return "nil" @@ -28673,6 +28807,7 @@ func (this *NodeSystemInfo) String() string { `KubeProxyVersion:` + fmt.Sprintf("%v", this.KubeProxyVersion) + `,`, `OperatingSystem:` + fmt.Sprintf("%v", this.OperatingSystem) + `,`, `Architecture:` + fmt.Sprintf("%v", this.Architecture) + `,`, + `Swap:` + strings.Replace(this.Swap.String(), "NodeSwapStatus", "NodeSwapStatus", 1) + `,`, `}`, }, "") return s @@ -29045,6 +29180,7 @@ func (this *PodCondition) String() string { `LastTransitionTime:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.LastTransitionTime), "Time", "v1.Time", 1), `&`, ``, 1) + `,`, `Reason:` + fmt.Sprintf("%v", this.Reason) + `,`, `Message:` + fmt.Sprintf("%v", this.Message) + `,`, + `ObservedGeneration:` + fmt.Sprintf("%v", this.ObservedGeneration) + `,`, `}`, }, "") return s @@ -29427,6 +29563,7 @@ func (this *PodStatus) String() string { `Resize:` + fmt.Sprintf("%v", this.Resize) + `,`, `ResourceClaimStatuses:` + repeatedStringForResourceClaimStatuses + `,`, `HostIPs:` + repeatedStringForHostIPs + `,`, + `ObservedGeneration:` + fmt.Sprintf("%v", this.ObservedGeneration) + `,`, `}`, }, "") return s @@ -37794,88 +37931,122 @@ func (m *ContainerStatus) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Resources == nil { - m.Resources = &ResourceRequirements{} - } - if err := m.Resources.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 12: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field VolumeMounts", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.VolumeMounts = append(m.VolumeMounts, VolumeMountStatus{}) - if err := m.VolumeMounts[len(m.VolumeMounts)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 13: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field User", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.User == nil { - m.User = &ContainerUser{} - } - if err := m.User.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if m.Resources == nil { + m.Resources = &ResourceRequirements{} + } + if err := m.Resources.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field VolumeMounts", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.VolumeMounts = append(m.VolumeMounts, VolumeMountStatus{}) + if err := m.VolumeMounts[len(m.VolumeMounts)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 13: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field User", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.User == nil { + m.User = &ContainerUser{} + } + if err := m.User.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 14: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AllocatedResourcesStatus", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AllocatedResourcesStatus = append(m.AllocatedResourcesStatus, ResourceStatus{}) + if err := m.AllocatedResourcesStatus[len(m.AllocatedResourcesStatus)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 14: + case 15: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AllocatedResourcesStatus", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field StopSignal", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -37885,25 +38056,24 @@ func (m *ContainerStatus) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.AllocatedResourcesStatus = append(m.AllocatedResourcesStatus, ResourceStatus{}) - if err := m.AllocatedResourcesStatus[len(m.AllocatedResourcesStatus)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + s := Signal(dAtA[iNdEx:postIndex]) + m.StopSignal = &s iNdEx = postIndex default: iNdEx = preIndex @@ -45056,6 +45226,39 @@ func (m *Lifecycle) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field StopSignal", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := Signal(dAtA[iNdEx:postIndex]) + m.StopSignal = &s + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -50743,6 +50946,76 @@ func (m *NodeStatus) Unmarshal(dAtA []byte) error { } return nil } +func (m *NodeSwapStatus) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NodeSwapStatus: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NodeSwapStatus: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Capacity", wireType) + } + var v int64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Capacity = &v + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *NodeSystemInfo) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -51092,6 +51365,42 @@ func (m *NodeSystemInfo) Unmarshal(dAtA []byte) error { } m.Architecture = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Swap", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Swap == nil { + m.Swap = &NodeSwapStatus{} + } + if err := m.Swap.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -56087,6 +56396,25 @@ func (m *PodCondition) Unmarshal(dAtA []byte) error { } m.Message = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ObservedGeneration", wireType) + } + m.ObservedGeneration = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ObservedGeneration |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -60340,6 +60668,25 @@ func (m *PodStatus) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 17: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ObservedGeneration", wireType) + } + m.ObservedGeneration = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ObservedGeneration |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/go-controller/vendor/k8s.io/api/core/v1/generated.proto b/go-controller/vendor/k8s.io/api/core/v1/generated.proto index 08706987c5..9b48fb1c39 100644 --- a/go-controller/vendor/k8s.io/api/core/v1/generated.proto +++ b/go-controller/vendor/k8s.io/api/core/v1/generated.proto @@ -1103,6 +1103,11 @@ message ContainerStatus { // +listType=map // +listMapKey=name repeated ResourceStatus allocatedResourcesStatus = 14; + + // StopSignal reports the effective stop signal for this container + // +featureGate=ContainerStopSignals + // +optional + optional string stopSignal = 15; } // ContainerUser represents user identity information @@ -1194,6 +1199,7 @@ message EmptyDirVolumeSource { } // EndpointAddress is a tuple that describes single IP address. +// Deprecated: This API is deprecated in v1.33+. // +structType=atomic message EndpointAddress { // The IP of this endpoint. @@ -1215,6 +1221,7 @@ message EndpointAddress { } // EndpointPort is a tuple that describes a single port. +// Deprecated: This API is deprecated in v1.33+. // +structType=atomic message EndpointPort { // The name of this port. This must match the 'name' field in the @@ -1265,6 +1272,8 @@ message EndpointPort { // // a: [ 10.10.1.1:8675, 10.10.2.2:8675 ], // b: [ 10.10.1.1:309, 10.10.2.2:309 ] +// +// Deprecated: This API is deprecated in v1.33+. message EndpointSubset { // IP addresses which offer the related ports that are marked as ready. These endpoints // should be considered safe for load balancers and clients to utilize. @@ -1298,6 +1307,11 @@ message EndpointSubset { // Ports: [{"name": "a", "port": 93}, {"name": "b", "port": 76}] // }, // ] +// +// Endpoints is a legacy API and does not contain information about all Service features. +// Use discoveryv1.EndpointSlice for complete information about Service endpoints. +// +// Deprecated: This API is deprecated in v1.33+. Use discoveryv1.EndpointSlice. message Endpoints { // Standard object's metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata @@ -1317,6 +1331,7 @@ message Endpoints { } // EndpointsList is a list of endpoints. +// Deprecated: This API is deprecated in v1.33+. message EndpointsList { // Standard list metadata. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds @@ -1327,9 +1342,9 @@ message EndpointsList { repeated Endpoints items = 2; } -// EnvFromSource represents the source of a set of ConfigMaps +// EnvFromSource represents the source of a set of ConfigMaps or Secrets message EnvFromSource { - // An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER. + // Optional text to prepend to the name of each environment variable. Must be a C_IDENTIFIER. // +optional optional string prefix = 1; @@ -2198,6 +2213,12 @@ message Lifecycle { // More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks // +optional optional LifecycleHandler preStop = 2; + + // StopSignal defines which signal will be sent to a container when it is being stopped. + // If not specified, the default is defined by the container runtime in use. + // StopSignal can only be set for Pods with a non-empty .spec.os.name + // +optional + optional string stopSignal = 3; } // LifecycleHandler defines a specific action that should be taken in a lifecycle @@ -2862,6 +2883,13 @@ message NodeStatus { optional NodeFeatures features = 13; } +// NodeSwapStatus represents swap memory information. +message NodeSwapStatus { + // Total amount of swap memory in bytes. + // +optional + optional int64 capacity = 1; +} + // NodeSystemInfo is a set of ids/uuids to uniquely identify the node. message NodeSystemInfo { // MachineID reported by the node. For unique machine identification @@ -2897,6 +2925,9 @@ message NodeSystemInfo { // The Architecture reported by the node optional string architecture = 10; + + // Swap Info reported by the node. + optional NodeSwapStatus swap = 11; } // ObjectFieldSelector selects an APIVersioned field of an object. @@ -3615,7 +3646,6 @@ message PodAffinityTerm { // pod labels will be ignored. The default value is empty. // The same key is forbidden to exist in both matchLabelKeys and labelSelector. // Also, matchLabelKeys cannot be set when labelSelector isn't set. - // This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). // // +listType=atomic // +optional @@ -3629,7 +3659,6 @@ message PodAffinityTerm { // pod labels will be ignored. The default value is empty. // The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. // Also, mismatchLabelKeys cannot be set when labelSelector isn't set. - // This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). // // +listType=atomic // +optional @@ -3702,6 +3731,12 @@ message PodCondition { // More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-conditions optional string type = 1; + // If set, this represents the .metadata.generation that the pod condition was set based upon. + // This is an alpha field. Enable PodObservedGenerationTracking to be able to use this field. + // +featureGate=PodObservedGenerationTracking + // +optional + optional int64 observedGeneration = 7; + // Status is the status of the condition. // Can be True, False, Unknown. // More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-conditions @@ -4138,7 +4173,7 @@ message PodSpec { // Init containers may not have Lifecycle actions, Readiness probes, Liveness probes, or Startup probes. // The resourceRequirements of an init container are taken into account during scheduling // by finding the highest request/limit for each resource type, and then using the max of - // of that value or the sum of the normal containers. Limits are applied to init containers + // that value or the sum of the normal containers. Limits are applied to init containers // in a similar fashion. // Init containers cannot currently be added or removed. // Cannot be updated. @@ -4487,6 +4522,12 @@ message PodSpec { // state of a system, especially if the node that hosts the pod cannot contact the control // plane. message PodStatus { + // If set, this represents the .metadata.generation that the pod status was set based upon. + // This is an alpha field. Enable PodObservedGenerationTracking to be able to use this field. + // +featureGate=PodObservedGenerationTracking + // +optional + optional int64 observedGeneration = 17; + // The phase of a Pod is a simple, high-level summary of where the Pod is in its lifecycle. // The conditions array, the reason and message fields, and the individual container status // arrays contain more detail about the pod's status. @@ -4618,6 +4659,9 @@ message PodStatus { // Status of resources resize desired for pod's containers. // It is empty if no resources resize is pending. // Any changes to container resources will automatically set this to "Proposed" + // Deprecated: Resize status is moved to two pod conditions PodResizePending and PodResizeInProgress. + // PodResizePending will track states where the spec has been resized, but the Kubelet has not yet allocated the resources. + // PodResizeInProgress will track in-progress resizes, and should be present whenever allocated resources != acknowledged resources. // +featureGate=InPlacePodVerticalScaling // +optional optional string resize = 14; @@ -5063,12 +5107,18 @@ message ReplicationControllerSpec { // Defaults to 1. // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#what-is-a-replicationcontroller // +optional + // +k8s:optional + // +default=1 + // +k8s:minimum=0 optional int32 replicas = 1; // Minimum number of seconds for which a newly created pod should be ready // without any of its container crashing, for it to be considered available. // Defaults to 0 (pod will be considered available as soon as it is ready) // +optional + // +k8s:optional + // +default=0 + // +k8s:minimum=0 optional int32 minReadySeconds = 4; // Selector is a label query over pods that should match the Replicas count. @@ -6110,13 +6160,12 @@ message ServiceSpec { // +optional optional string internalTrafficPolicy = 22; - // TrafficDistribution offers a way to express preferences for how traffic is - // distributed to Service endpoints. Implementations can use this field as a - // hint, but are not required to guarantee strict adherence. If the field is - // not set, the implementation will apply its default routing strategy. If set - // to "PreferClose", implementations should prioritize endpoints that are - // topologically close (e.g., same zone). - // This is a beta field and requires enabling ServiceTrafficDistribution feature. + // TrafficDistribution offers a way to express preferences for how traffic + // is distributed to Service endpoints. Implementations can use this field + // as a hint, but are not required to guarantee strict adherence. If the + // field is not set, the implementation will apply its default routing + // strategy. If set to "PreferClose", implementations should prioritize + // endpoints that are in the same zone. // +featureGate=ServiceTrafficDistribution // +optional optional string trafficDistribution = 23; @@ -6411,7 +6460,6 @@ message TopologySpreadConstraint { // - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. // // If this value is nil, the behavior is equivalent to the Honor policy. - // This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. // +optional optional string nodeAffinityPolicy = 6; @@ -6422,7 +6470,6 @@ message TopologySpreadConstraint { // - Ignore: node taints are ignored. All nodes are included. // // If this value is nil, the behavior is equivalent to the Ignore policy. - // This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. // +optional optional string nodeTaintsPolicy = 7; @@ -6854,7 +6901,7 @@ message VolumeSource { // The types of objects that may be mounted by this volume are defined by the container runtime implementation on a host machine and at minimum must include all valid types supported by the container image field. // The OCI object gets mounted in a single directory (spec.containers[*].volumeMounts.mountPath) by merging the manifest layers in the same way as for container images. // The volume will be mounted read-only (ro) and non-executable files (noexec). - // Sub path mounts for containers are not supported (spec.containers[*].volumeMounts.subpath). + // Sub path mounts for containers are not supported (spec.containers[*].volumeMounts.subpath) before 1.33. // The field spec.securityContext.fsGroupChangePolicy has no effect on this volume type. // +featureGate=ImageVolume // +optional diff --git a/go-controller/vendor/k8s.io/api/core/v1/lifecycle.go b/go-controller/vendor/k8s.io/api/core/v1/lifecycle.go index 21ca90e815..21b931b67a 100644 --- a/go-controller/vendor/k8s.io/api/core/v1/lifecycle.go +++ b/go-controller/vendor/k8s.io/api/core/v1/lifecycle.go @@ -16,6 +16,10 @@ limitations under the License. package v1 +import ( + "k8s.io/apimachinery/pkg/runtime/schema" +) + // APILifecycleIntroduced returns the release in which the API struct was introduced as int versions of major and minor for comparison. func (in *ComponentStatus) APILifecycleIntroduced() (major, minor int) { return 1, 0 @@ -35,3 +39,23 @@ func (in *ComponentStatusList) APILifecycleIntroduced() (major, minor int) { func (in *ComponentStatusList) APILifecycleDeprecated() (major, minor int) { return 1, 19 } + +// APILifecycleDeprecated returns the release in which the API struct was or will be deprecated as int versions of major and minor for comparison. +func (in *Endpoints) APILifecycleDeprecated() (major, minor int) { + return 1, 33 +} + +// APILifecycleReplacement returns the GVK of the replacement for the given API +func (in *Endpoints) APILifecycleReplacement() schema.GroupVersionKind { + return schema.GroupVersionKind{Group: "discovery.k8s.io", Version: "v1", Kind: "EndpointSlice"} +} + +// APILifecycleDeprecated returns the release in which the API struct was or will be deprecated as int versions of major and minor for comparison. +func (in *EndpointsList) APILifecycleDeprecated() (major, minor int) { + return 1, 33 +} + +// APILifecycleReplacement returns the GVK of the replacement for the given API +func (in *EndpointsList) APILifecycleReplacement() schema.GroupVersionKind { + return schema.GroupVersionKind{Group: "discovery.k8s.io", Version: "v1", Kind: "EndpointSliceList"} +} diff --git a/go-controller/vendor/k8s.io/api/core/v1/types.go b/go-controller/vendor/k8s.io/api/core/v1/types.go index fb2c1c7453..f7641e485a 100644 --- a/go-controller/vendor/k8s.io/api/core/v1/types.go +++ b/go-controller/vendor/k8s.io/api/core/v1/types.go @@ -217,7 +217,7 @@ type VolumeSource struct { // The types of objects that may be mounted by this volume are defined by the container runtime implementation on a host machine and at minimum must include all valid types supported by the container image field. // The OCI object gets mounted in a single directory (spec.containers[*].volumeMounts.mountPath) by merging the manifest layers in the same way as for container images. // The volume will be mounted read-only (ro) and non-executable files (noexec). - // Sub path mounts for containers are not supported (spec.containers[*].volumeMounts.subpath). + // Sub path mounts for containers are not supported (spec.containers[*].volumeMounts.subpath) before 1.33. // The field spec.securityContext.fsGroupChangePolicy has no effect on this volume type. // +featureGate=ImageVolume // +optional @@ -2437,9 +2437,9 @@ type SecretKeySelector struct { Optional *bool `json:"optional,omitempty" protobuf:"varint,3,opt,name=optional"` } -// EnvFromSource represents the source of a set of ConfigMaps +// EnvFromSource represents the source of a set of ConfigMaps or Secrets type EnvFromSource struct { - // An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER. + // Optional text to prepend to the name of each environment variable. Must be a C_IDENTIFIER. // +optional Prefix string `json:"prefix,omitempty" protobuf:"bytes,1,opt,name=prefix"` // The ConfigMap to select from @@ -2980,6 +2980,78 @@ type LifecycleHandler struct { Sleep *SleepAction `json:"sleep,omitempty" protobuf:"bytes,4,opt,name=sleep"` } +// Signal defines the stop signal of containers +// +enum +type Signal string + +const ( + SIGABRT Signal = "SIGABRT" + SIGALRM Signal = "SIGALRM" + SIGBUS Signal = "SIGBUS" + SIGCHLD Signal = "SIGCHLD" + SIGCLD Signal = "SIGCLD" + SIGCONT Signal = "SIGCONT" + SIGFPE Signal = "SIGFPE" + SIGHUP Signal = "SIGHUP" + SIGILL Signal = "SIGILL" + SIGINT Signal = "SIGINT" + SIGIO Signal = "SIGIO" + SIGIOT Signal = "SIGIOT" + SIGKILL Signal = "SIGKILL" + SIGPIPE Signal = "SIGPIPE" + SIGPOLL Signal = "SIGPOLL" + SIGPROF Signal = "SIGPROF" + SIGPWR Signal = "SIGPWR" + SIGQUIT Signal = "SIGQUIT" + SIGSEGV Signal = "SIGSEGV" + SIGSTKFLT Signal = "SIGSTKFLT" + SIGSTOP Signal = "SIGSTOP" + SIGSYS Signal = "SIGSYS" + SIGTERM Signal = "SIGTERM" + SIGTRAP Signal = "SIGTRAP" + SIGTSTP Signal = "SIGTSTP" + SIGTTIN Signal = "SIGTTIN" + SIGTTOU Signal = "SIGTTOU" + SIGURG Signal = "SIGURG" + SIGUSR1 Signal = "SIGUSR1" + SIGUSR2 Signal = "SIGUSR2" + SIGVTALRM Signal = "SIGVTALRM" + SIGWINCH Signal = "SIGWINCH" + SIGXCPU Signal = "SIGXCPU" + SIGXFSZ Signal = "SIGXFSZ" + SIGRTMIN Signal = "SIGRTMIN" + SIGRTMINPLUS1 Signal = "SIGRTMIN+1" + SIGRTMINPLUS2 Signal = "SIGRTMIN+2" + SIGRTMINPLUS3 Signal = "SIGRTMIN+3" + SIGRTMINPLUS4 Signal = "SIGRTMIN+4" + SIGRTMINPLUS5 Signal = "SIGRTMIN+5" + SIGRTMINPLUS6 Signal = "SIGRTMIN+6" + SIGRTMINPLUS7 Signal = "SIGRTMIN+7" + SIGRTMINPLUS8 Signal = "SIGRTMIN+8" + SIGRTMINPLUS9 Signal = "SIGRTMIN+9" + SIGRTMINPLUS10 Signal = "SIGRTMIN+10" + SIGRTMINPLUS11 Signal = "SIGRTMIN+11" + SIGRTMINPLUS12 Signal = "SIGRTMIN+12" + SIGRTMINPLUS13 Signal = "SIGRTMIN+13" + SIGRTMINPLUS14 Signal = "SIGRTMIN+14" + SIGRTMINPLUS15 Signal = "SIGRTMIN+15" + SIGRTMAXMINUS14 Signal = "SIGRTMAX-14" + SIGRTMAXMINUS13 Signal = "SIGRTMAX-13" + SIGRTMAXMINUS12 Signal = "SIGRTMAX-12" + SIGRTMAXMINUS11 Signal = "SIGRTMAX-11" + SIGRTMAXMINUS10 Signal = "SIGRTMAX-10" + SIGRTMAXMINUS9 Signal = "SIGRTMAX-9" + SIGRTMAXMINUS8 Signal = "SIGRTMAX-8" + SIGRTMAXMINUS7 Signal = "SIGRTMAX-7" + SIGRTMAXMINUS6 Signal = "SIGRTMAX-6" + SIGRTMAXMINUS5 Signal = "SIGRTMAX-5" + SIGRTMAXMINUS4 Signal = "SIGRTMAX-4" + SIGRTMAXMINUS3 Signal = "SIGRTMAX-3" + SIGRTMAXMINUS2 Signal = "SIGRTMAX-2" + SIGRTMAXMINUS1 Signal = "SIGRTMAX-1" + SIGRTMAX Signal = "SIGRTMAX" +) + // Lifecycle describes actions that the management system should take in response to container lifecycle // events. For the PostStart and PreStop lifecycle handlers, management of the container blocks // until the action is complete, unless the container process fails, in which case the handler is aborted. @@ -3001,6 +3073,11 @@ type Lifecycle struct { // More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks // +optional PreStop *LifecycleHandler `json:"preStop,omitempty" protobuf:"bytes,2,opt,name=preStop"` + // StopSignal defines which signal will be sent to a container when it is being stopped. + // If not specified, the default is defined by the container runtime in use. + // StopSignal can only be set for Pods with a non-empty .spec.os.name + // +optional + StopSignal *Signal `json:"stopSignal,omitempty" protobuf:"bytes,3,opt,name=stopSignal"` } type ConditionStatus string @@ -3154,6 +3231,10 @@ type ContainerStatus struct { // +listType=map // +listMapKey=name AllocatedResourcesStatus []ResourceStatus `json:"allocatedResourcesStatus,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,14,rep,name=allocatedResourcesStatus"` + // StopSignal reports the effective stop signal for this container + // +featureGate=ContainerStopSignals + // +optional + StopSignal *Signal `json:"stopSignal,omitempty" protobuf:"bytes,15,opt,name=stopSignal"` } // ResourceStatus represents the status of a single resource allocated to a Pod. @@ -3278,6 +3359,17 @@ const ( // PodReadyToStartContainers pod sandbox is successfully configured and // the pod is ready to launch containers. PodReadyToStartContainers PodConditionType = "PodReadyToStartContainers" + // PodResizePending indicates that the pod has been resized, but kubelet has not + // yet allocated the resources. If both PodResizePending and PodResizeInProgress + // are set, it means that a new resize was requested in the middle of a previous + // pod resize that is still in progress. + PodResizePending PodConditionType = "PodResizePending" + // PodResizeInProgress indicates that a resize is in progress, and is present whenever + // the Kubelet has allocated resources for the resize, but has not yet actuated all of + // the required changes. + // If both PodResizePending and PodResizeInProgress are set, it means that a new resize was + // requested in the middle of a previous pod resize that is still in progress. + PodResizeInProgress PodConditionType = "PodResizeInProgress" ) // These are reasons for a pod's transition to a condition. @@ -3301,6 +3393,18 @@ const ( // PodReasonPreemptionByScheduler reason in DisruptionTarget pod condition indicates that the // disruption was initiated by scheduler's preemption. PodReasonPreemptionByScheduler = "PreemptionByScheduler" + + // PodReasonDeferred reason in PodResizePending pod condition indicates the proposed resize is feasible in + // theory (it fits on this node) but is not possible right now. + PodReasonDeferred = "Deferred" + + // PodReasonInfeasible reason in PodResizePending pod condition indicates the proposed resize is not + // feasible and is rejected; it may not be re-evaluated + PodReasonInfeasible = "Infeasible" + + // PodReasonError reason in PodResizeInProgress pod condition indicates that an error occurred while + // actuating the resize. + PodReasonError = "Error" ) // PodCondition contains details for the current condition of this pod. @@ -3308,6 +3412,11 @@ type PodCondition struct { // Type is the type of the condition. // More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-conditions Type PodConditionType `json:"type" protobuf:"bytes,1,opt,name=type,casttype=PodConditionType"` + // If set, this represents the .metadata.generation that the pod condition was set based upon. + // This is an alpha field. Enable PodObservedGenerationTracking to be able to use this field. + // +featureGate=PodObservedGenerationTracking + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty" protobuf:"varint,7,opt,name=observedGeneration"` // Status is the status of the condition. // Can be True, False, Unknown. // More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-conditions @@ -3326,12 +3435,10 @@ type PodCondition struct { Message string `json:"message,omitempty" protobuf:"bytes,6,opt,name=message"` } -// PodResizeStatus shows status of desired resize of a pod's containers. +// Deprecated: PodResizeStatus shows status of desired resize of a pod's containers. type PodResizeStatus string const ( - // Pod resources resize has been requested and will be evaluated by node. - PodResizeStatusProposed PodResizeStatus = "Proposed" // Pod resources resize has been accepted by node and is being actuated. PodResizeStatusInProgress PodResizeStatus = "InProgress" // Node cannot resize the pod at this time and will keep retrying. @@ -3627,7 +3734,6 @@ type PodAffinityTerm struct { // pod labels will be ignored. The default value is empty. // The same key is forbidden to exist in both matchLabelKeys and labelSelector. // Also, matchLabelKeys cannot be set when labelSelector isn't set. - // This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). // // +listType=atomic // +optional @@ -3640,7 +3746,6 @@ type PodAffinityTerm struct { // pod labels will be ignored. The default value is empty. // The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. // Also, mismatchLabelKeys cannot be set when labelSelector isn't set. - // This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). // // +listType=atomic // +optional @@ -3792,7 +3897,7 @@ type PodSpec struct { // Init containers may not have Lifecycle actions, Readiness probes, Liveness probes, or Startup probes. // The resourceRequirements of an init container are taken into account during scheduling // by finding the highest request/limit for each resource type, and then using the max of - // of that value or the sum of the normal containers. Limits are applied to init containers + // that value or the sum of the normal containers. Limits are applied to init containers // in a similar fashion. // Init containers cannot currently be added or removed. // Cannot be updated. @@ -4301,7 +4406,6 @@ type TopologySpreadConstraint struct { // - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. // // If this value is nil, the behavior is equivalent to the Honor policy. - // This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. // +optional NodeAffinityPolicy *NodeInclusionPolicy `json:"nodeAffinityPolicy,omitempty" protobuf:"bytes,6,opt,name=nodeAffinityPolicy"` // NodeTaintsPolicy indicates how we will treat node taints when calculating @@ -4311,7 +4415,6 @@ type TopologySpreadConstraint struct { // - Ignore: node taints are ignored. All nodes are included. // // If this value is nil, the behavior is equivalent to the Ignore policy. - // This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag. // +optional NodeTaintsPolicy *NodeInclusionPolicy `json:"nodeTaintsPolicy,omitempty" protobuf:"bytes,7,opt,name=nodeTaintsPolicy"` // MatchLabelKeys is a set of pod label keys to select the pods over which @@ -4841,6 +4944,11 @@ type EphemeralContainer struct { // state of a system, especially if the node that hosts the pod cannot contact the control // plane. type PodStatus struct { + // If set, this represents the .metadata.generation that the pod status was set based upon. + // This is an alpha field. Enable PodObservedGenerationTracking to be able to use this field. + // +featureGate=PodObservedGenerationTracking + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty" protobuf:"varint,17,opt,name=observedGeneration"` // The phase of a Pod is a simple, high-level summary of where the Pod is in its lifecycle. // The conditions array, the reason and message fields, and the individual container status // arrays contain more detail about the pod's status. @@ -4968,6 +5076,9 @@ type PodStatus struct { // Status of resources resize desired for pod's containers. // It is empty if no resources resize is pending. // Any changes to container resources will automatically set this to "Proposed" + // Deprecated: Resize status is moved to two pod conditions PodResizePending and PodResizeInProgress. + // PodResizePending will track states where the spec has been resized, but the Kubelet has not yet allocated the resources. + // PodResizeInProgress will track in-progress resizes, and should be present whenever allocated resources != acknowledged resources. // +featureGate=InPlacePodVerticalScaling // +optional Resize PodResizeStatus `json:"resize,omitempty" protobuf:"bytes,14,opt,name=resize,casttype=PodResizeStatus"` @@ -5099,12 +5210,18 @@ type ReplicationControllerSpec struct { // Defaults to 1. // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#what-is-a-replicationcontroller // +optional + // +k8s:optional + // +default=1 + // +k8s:minimum=0 Replicas *int32 `json:"replicas,omitempty" protobuf:"varint,1,opt,name=replicas"` // Minimum number of seconds for which a newly created pod should be ready // without any of its container crashing, for it to be considered available. // Defaults to 0 (pod will be considered available as soon as it is ready) // +optional + // +k8s:optional + // +default=0 + // +k8s:minimum=0 MinReadySeconds int32 `json:"minReadySeconds,omitempty" protobuf:"varint,4,opt,name=minReadySeconds"` // Selector is a label query over pods that should match the Replicas count. @@ -5334,14 +5451,27 @@ const ( // These are valid values for the TrafficDistribution field of a Service. const ( - // Indicates a preference for routing traffic to endpoints that are - // topologically proximate to the client. The interpretation of "topologically - // proximate" may vary across implementations and could encompass endpoints - // within the same node, rack, zone, or even region. Setting this value gives - // implementations permission to make different tradeoffs, e.g. optimizing for - // proximity rather than equal distribution of load. Users should not set this - // value if such tradeoffs are not acceptable. + // Indicates a preference for routing traffic to endpoints that are in the same + // zone as the client. Users should not set this value unless they have ensured + // that clients and endpoints are distributed in such a way that the "same zone" + // preference will not result in endpoints getting overloaded. ServiceTrafficDistributionPreferClose = "PreferClose" + + // Indicates a preference for routing traffic to endpoints that are in the same + // zone as the client. Users should not set this value unless they have ensured + // that clients and endpoints are distributed in such a way that the "same zone" + // preference will not result in endpoints getting overloaded. + // This is an alias for "PreferClose", but it is an Alpha feature and is only + // recognized if the PreferSameTrafficDistribution feature gate is enabled. + ServiceTrafficDistributionPreferSameZone = "PreferSameZone" + + // Indicates a preference for routing traffic to endpoints that are on the same + // node as the client. Users should not set this value unless they have ensured + // that clients and endpoints are distributed in such a way that the "same node" + // preference will not result in endpoints getting overloaded. + // This is an Alpha feature and is only recognized if the + // PreferSameTrafficDistribution feature gate is enabled. + ServiceTrafficDistributionPreferSameNode = "PreferSameNode" ) // These are the valid conditions of a service. @@ -5689,13 +5819,12 @@ type ServiceSpec struct { // +optional InternalTrafficPolicy *ServiceInternalTrafficPolicy `json:"internalTrafficPolicy,omitempty" protobuf:"bytes,22,opt,name=internalTrafficPolicy"` - // TrafficDistribution offers a way to express preferences for how traffic is - // distributed to Service endpoints. Implementations can use this field as a - // hint, but are not required to guarantee strict adherence. If the field is - // not set, the implementation will apply its default routing strategy. If set - // to "PreferClose", implementations should prioritize endpoints that are - // topologically close (e.g., same zone). - // This is a beta field and requires enabling ServiceTrafficDistribution feature. + // TrafficDistribution offers a way to express preferences for how traffic + // is distributed to Service endpoints. Implementations can use this field + // as a hint, but are not required to guarantee strict adherence. If the + // field is not set, the implementation will apply its default routing + // strategy. If set to "PreferClose", implementations should prioritize + // endpoints that are in the same zone. // +featureGate=ServiceTrafficDistribution // +optional TrafficDistribution *string `json:"trafficDistribution,omitempty" protobuf:"bytes,23,opt,name=trafficDistribution"` @@ -5888,6 +6017,11 @@ type ServiceAccountList struct { // Ports: [{"name": "a", "port": 93}, {"name": "b", "port": 76}] // }, // ] +// +// Endpoints is a legacy API and does not contain information about all Service features. +// Use discoveryv1.EndpointSlice for complete information about Service endpoints. +// +// Deprecated: This API is deprecated in v1.33+. Use discoveryv1.EndpointSlice. type Endpoints struct { metav1.TypeMeta `json:",inline"` // Standard object's metadata. @@ -5920,6 +6054,8 @@ type Endpoints struct { // // a: [ 10.10.1.1:8675, 10.10.2.2:8675 ], // b: [ 10.10.1.1:309, 10.10.2.2:309 ] +// +// Deprecated: This API is deprecated in v1.33+. type EndpointSubset struct { // IP addresses which offer the related ports that are marked as ready. These endpoints // should be considered safe for load balancers and clients to utilize. @@ -5939,6 +6075,7 @@ type EndpointSubset struct { } // EndpointAddress is a tuple that describes single IP address. +// Deprecated: This API is deprecated in v1.33+. // +structType=atomic type EndpointAddress struct { // The IP of this endpoint. @@ -5957,6 +6094,7 @@ type EndpointAddress struct { } // EndpointPort is a tuple that describes a single port. +// Deprecated: This API is deprecated in v1.33+. // +structType=atomic type EndpointPort struct { // The name of this port. This must match the 'name' field in the @@ -5998,6 +6136,7 @@ type EndpointPort struct { // +k8s:prerelease-lifecycle-gen:introduced=1.0 // EndpointsList is a list of endpoints. +// Deprecated: This API is deprecated in v1.33+. type EndpointsList struct { metav1.TypeMeta `json:",inline"` // Standard list metadata. @@ -6166,6 +6305,15 @@ type NodeSystemInfo struct { OperatingSystem string `json:"operatingSystem" protobuf:"bytes,9,opt,name=operatingSystem"` // The Architecture reported by the node Architecture string `json:"architecture" protobuf:"bytes,10,opt,name=architecture"` + // Swap Info reported by the node. + Swap *NodeSwapStatus `json:"swap,omitempty" protobuf:"bytes,11,opt,name=swap"` +} + +// NodeSwapStatus represents swap memory information. +type NodeSwapStatus struct { + // Total amount of swap memory in bytes. + // +optional + Capacity *int64 `json:"capacity,omitempty" protobuf:"varint,1,opt,name=capacity"` } // NodeConfigStatus describes the status of the config assigned by Node.Spec.ConfigSource. @@ -7267,6 +7415,9 @@ const ( ResourceQuotaScopePriorityClass ResourceQuotaScope = "PriorityClass" // Match all pod objects that have cross-namespace pod (anti)affinity mentioned. ResourceQuotaScopeCrossNamespacePodAffinity ResourceQuotaScope = "CrossNamespacePodAffinity" + + // Match all pvc objects that have volume attributes class mentioned. + ResourceQuotaScopeVolumeAttributesClass ResourceQuotaScope = "VolumeAttributesClass" ) // ResourceQuotaSpec defines the desired hard limits to enforce for Quota. diff --git a/go-controller/vendor/k8s.io/api/core/v1/types_swagger_doc_generated.go b/go-controller/vendor/k8s.io/api/core/v1/types_swagger_doc_generated.go index 89ce3d2303..9e987eefdd 100644 --- a/go-controller/vendor/k8s.io/api/core/v1/types_swagger_doc_generated.go +++ b/go-controller/vendor/k8s.io/api/core/v1/types_swagger_doc_generated.go @@ -474,6 +474,7 @@ var map_ContainerStatus = map[string]string{ "volumeMounts": "Status of volume mounts.", "user": "User represents user identity information initially attached to the first process of the container", "allocatedResourcesStatus": "AllocatedResourcesStatus represents the status of various resources allocated for this Pod.", + "stopSignal": "StopSignal reports the effective stop signal for this container", } func (ContainerStatus) SwaggerDoc() map[string]string { @@ -540,7 +541,7 @@ func (EmptyDirVolumeSource) SwaggerDoc() map[string]string { } var map_EndpointAddress = map[string]string{ - "": "EndpointAddress is a tuple that describes single IP address.", + "": "EndpointAddress is a tuple that describes single IP address. Deprecated: This API is deprecated in v1.33+.", "ip": "The IP of this endpoint. May not be loopback (127.0.0.0/8 or ::1), link-local (169.254.0.0/16 or fe80::/10), or link-local multicast (224.0.0.0/24 or ff02::/16).", "hostname": "The Hostname of this endpoint", "nodeName": "Optional: Node hosting this endpoint. This can be used to determine endpoints local to a node.", @@ -552,7 +553,7 @@ func (EndpointAddress) SwaggerDoc() map[string]string { } var map_EndpointPort = map[string]string{ - "": "EndpointPort is a tuple that describes a single port.", + "": "EndpointPort is a tuple that describes a single port. Deprecated: This API is deprecated in v1.33+.", "name": "The name of this port. This must match the 'name' field in the corresponding ServicePort. Must be a DNS_LABEL. Optional only if one port is defined.", "port": "The port number of the endpoint.", "protocol": "The IP protocol for this port. Must be UDP, TCP, or SCTP. Default is TCP.", @@ -564,7 +565,7 @@ func (EndpointPort) SwaggerDoc() map[string]string { } var map_EndpointSubset = map[string]string{ - "": "EndpointSubset is a group of addresses with a common set of ports. The expanded set of endpoints is the Cartesian product of Addresses x Ports. For example, given:\n\n\t{\n\t Addresses: [{\"ip\": \"10.10.1.1\"}, {\"ip\": \"10.10.2.2\"}],\n\t Ports: [{\"name\": \"a\", \"port\": 8675}, {\"name\": \"b\", \"port\": 309}]\n\t}\n\nThe resulting set of endpoints can be viewed as:\n\n\ta: [ 10.10.1.1:8675, 10.10.2.2:8675 ],\n\tb: [ 10.10.1.1:309, 10.10.2.2:309 ]", + "": "EndpointSubset is a group of addresses with a common set of ports. The expanded set of endpoints is the Cartesian product of Addresses x Ports. For example, given:\n\n\t{\n\t Addresses: [{\"ip\": \"10.10.1.1\"}, {\"ip\": \"10.10.2.2\"}],\n\t Ports: [{\"name\": \"a\", \"port\": 8675}, {\"name\": \"b\", \"port\": 309}]\n\t}\n\nThe resulting set of endpoints can be viewed as:\n\n\ta: [ 10.10.1.1:8675, 10.10.2.2:8675 ],\n\tb: [ 10.10.1.1:309, 10.10.2.2:309 ]\n\nDeprecated: This API is deprecated in v1.33+.", "addresses": "IP addresses which offer the related ports that are marked as ready. These endpoints should be considered safe for load balancers and clients to utilize.", "notReadyAddresses": "IP addresses which offer the related ports but are not currently marked as ready because they have not yet finished starting, have recently failed a readiness check, or have recently failed a liveness check.", "ports": "Port numbers available on the related IP addresses.", @@ -575,7 +576,7 @@ func (EndpointSubset) SwaggerDoc() map[string]string { } var map_Endpoints = map[string]string{ - "": "Endpoints is a collection of endpoints that implement the actual service. Example:\n\n\t Name: \"mysvc\",\n\t Subsets: [\n\t {\n\t Addresses: [{\"ip\": \"10.10.1.1\"}, {\"ip\": \"10.10.2.2\"}],\n\t Ports: [{\"name\": \"a\", \"port\": 8675}, {\"name\": \"b\", \"port\": 309}]\n\t },\n\t {\n\t Addresses: [{\"ip\": \"10.10.3.3\"}],\n\t Ports: [{\"name\": \"a\", \"port\": 93}, {\"name\": \"b\", \"port\": 76}]\n\t },\n\t]", + "": "Endpoints is a collection of endpoints that implement the actual service. Example:\n\n\t Name: \"mysvc\",\n\t Subsets: [\n\t {\n\t Addresses: [{\"ip\": \"10.10.1.1\"}, {\"ip\": \"10.10.2.2\"}],\n\t Ports: [{\"name\": \"a\", \"port\": 8675}, {\"name\": \"b\", \"port\": 309}]\n\t },\n\t {\n\t Addresses: [{\"ip\": \"10.10.3.3\"}],\n\t Ports: [{\"name\": \"a\", \"port\": 93}, {\"name\": \"b\", \"port\": 76}]\n\t },\n\t]\n\nEndpoints is a legacy API and does not contain information about all Service features. Use discoveryv1.EndpointSlice for complete information about Service endpoints.\n\nDeprecated: This API is deprecated in v1.33+. Use discoveryv1.EndpointSlice.", "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", "subsets": "The set of all endpoints is the union of all subsets. Addresses are placed into subsets according to the IPs they share. A single address with multiple ports, some of which are ready and some of which are not (because they come from different containers) will result in the address being displayed in different subsets for the different ports. No address will appear in both Addresses and NotReadyAddresses in the same subset. Sets of addresses and ports that comprise a service.", } @@ -585,7 +586,7 @@ func (Endpoints) SwaggerDoc() map[string]string { } var map_EndpointsList = map[string]string{ - "": "EndpointsList is a list of endpoints.", + "": "EndpointsList is a list of endpoints. Deprecated: This API is deprecated in v1.33+.", "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", "items": "List of endpoints.", } @@ -595,8 +596,8 @@ func (EndpointsList) SwaggerDoc() map[string]string { } var map_EnvFromSource = map[string]string{ - "": "EnvFromSource represents the source of a set of ConfigMaps", - "prefix": "An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER.", + "": "EnvFromSource represents the source of a set of ConfigMaps or Secrets", + "prefix": "Optional text to prepend to the name of each environment variable. Must be a C_IDENTIFIER.", "configMapRef": "The ConfigMap to select from", "secretRef": "The Secret to select from", } @@ -957,9 +958,10 @@ func (KeyToPath) SwaggerDoc() map[string]string { } var map_Lifecycle = map[string]string{ - "": "Lifecycle describes actions that the management system should take in response to container lifecycle events. For the PostStart and PreStop lifecycle handlers, management of the container blocks until the action is complete, unless the container process fails, in which case the handler is aborted.", - "postStart": "PostStart is called immediately after a container is created. If the handler fails, the container is terminated and restarted according to its restart policy. Other management of the container blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks", - "preStop": "PreStop is called immediately before a container is terminated due to an API request or management event such as liveness/startup probe failure, preemption, resource contention, etc. The handler is not called if the container crashes or exits. The Pod's termination grace period countdown begins before the PreStop hook is executed. Regardless of the outcome of the handler, the container will eventually terminate within the Pod's termination grace period (unless delayed by finalizers). Other management of the container blocks until the hook completes or until the termination grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks", + "": "Lifecycle describes actions that the management system should take in response to container lifecycle events. For the PostStart and PreStop lifecycle handlers, management of the container blocks until the action is complete, unless the container process fails, in which case the handler is aborted.", + "postStart": "PostStart is called immediately after a container is created. If the handler fails, the container is terminated and restarted according to its restart policy. Other management of the container blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks", + "preStop": "PreStop is called immediately before a container is terminated due to an API request or management event such as liveness/startup probe failure, preemption, resource contention, etc. The handler is not called if the container crashes or exits. The Pod's termination grace period countdown begins before the PreStop hook is executed. Regardless of the outcome of the handler, the container will eventually terminate within the Pod's termination grace period (unless delayed by finalizers). Other management of the container blocks until the hook completes or until the termination grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks", + "stopSignal": "StopSignal defines which signal will be sent to a container when it is being stopped. If not specified, the default is defined by the container runtime in use. StopSignal can only be set for Pods with a non-empty .spec.os.name", } func (Lifecycle) SwaggerDoc() map[string]string { @@ -1335,6 +1337,15 @@ func (NodeStatus) SwaggerDoc() map[string]string { return map_NodeStatus } +var map_NodeSwapStatus = map[string]string{ + "": "NodeSwapStatus represents swap memory information.", + "capacity": "Total amount of swap memory in bytes.", +} + +func (NodeSwapStatus) SwaggerDoc() map[string]string { + return map_NodeSwapStatus +} + var map_NodeSystemInfo = map[string]string{ "": "NodeSystemInfo is a set of ids/uuids to uniquely identify the node.", "machineID": "MachineID reported by the node. For unique machine identification in the cluster this field is preferred. Learn more from man(5) machine-id: http://man7.org/linux/man-pages/man5/machine-id.5.html", @@ -1347,6 +1358,7 @@ var map_NodeSystemInfo = map[string]string{ "kubeProxyVersion": "Deprecated: KubeProxy Version reported by the node.", "operatingSystem": "The Operating System reported by the node", "architecture": "The Architecture reported by the node", + "swap": "Swap Info reported by the node.", } func (NodeSystemInfo) SwaggerDoc() map[string]string { @@ -1583,8 +1595,8 @@ var map_PodAffinityTerm = map[string]string{ "namespaces": "namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means \"this pod's namespace\".", "topologyKey": "This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed.", "namespaceSelector": "A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means \"this pod's namespace\". An empty selector ({}) matches all namespaces.", - "matchLabelKeys": "MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both matchLabelKeys and labelSelector. Also, matchLabelKeys cannot be set when labelSelector isn't set. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).", - "mismatchLabelKeys": "MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. Also, mismatchLabelKeys cannot be set when labelSelector isn't set. This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default).", + "matchLabelKeys": "MatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `labelSelector` as `key in (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both matchLabelKeys and labelSelector. Also, matchLabelKeys cannot be set when labelSelector isn't set.", + "mismatchLabelKeys": "MismatchLabelKeys is a set of pod label keys to select which pods will be taken into consideration. The keys are used to lookup values from the incoming pod labels, those key-value labels are merged with `labelSelector` as `key notin (value)` to select the group of existing pods which pods will be taken into consideration for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming pod labels will be ignored. The default value is empty. The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. Also, mismatchLabelKeys cannot be set when labelSelector isn't set.", } func (PodAffinityTerm) SwaggerDoc() map[string]string { @@ -1617,6 +1629,7 @@ func (PodAttachOptions) SwaggerDoc() map[string]string { var map_PodCondition = map[string]string{ "": "PodCondition contains details for the current condition of this pod.", "type": "Type is the type of the condition. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-conditions", + "observedGeneration": "If set, this represents the .metadata.generation that the pod condition was set based upon. This is an alpha field. Enable PodObservedGenerationTracking to be able to use this field.", "status": "Status is the status of the condition. Can be True, False, Unknown. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-conditions", "lastProbeTime": "Last time we probed the condition.", "lastTransitionTime": "Last time the condition transitioned from one status to another.", @@ -1799,7 +1812,7 @@ func (PodSignature) SwaggerDoc() map[string]string { var map_PodSpec = map[string]string{ "": "PodSpec is a description of a pod.", "volumes": "List of volumes that can be mounted by containers belonging to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes", - "initContainers": "List of initialization containers belonging to the pod. Init containers are executed in order prior to containers being started. If any init container fails, the pod is considered to have failed and is handled according to its restartPolicy. The name for an init container or normal container must be unique among all containers. Init containers may not have Lifecycle actions, Readiness probes, Liveness probes, or Startup probes. The resourceRequirements of an init container are taken into account during scheduling by finding the highest request/limit for each resource type, and then using the max of of that value or the sum of the normal containers. Limits are applied to init containers in a similar fashion. Init containers cannot currently be added or removed. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/", + "initContainers": "List of initialization containers belonging to the pod. Init containers are executed in order prior to containers being started. If any init container fails, the pod is considered to have failed and is handled according to its restartPolicy. The name for an init container or normal container must be unique among all containers. Init containers may not have Lifecycle actions, Readiness probes, Liveness probes, or Startup probes. The resourceRequirements of an init container are taken into account during scheduling by finding the highest request/limit for each resource type, and then using the max of that value or the sum of the normal containers. Limits are applied to init containers in a similar fashion. Init containers cannot currently be added or removed. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/", "containers": "List of containers belonging to the pod. Containers cannot currently be added or removed. There must be at least one container in a Pod. Cannot be updated.", "ephemeralContainers": "List of ephemeral containers run in this pod. Ephemeral containers may be run in an existing pod to perform user-initiated actions such as debugging. This list cannot be specified when creating a pod, and it cannot be modified by updating the pod spec. In order to add an ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource.", "restartPolicy": "Restart policy for all containers within the pod. One of Always, OnFailure, Never. In some contexts, only a subset of those values may be permitted. Default to Always. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy", @@ -1846,6 +1859,7 @@ func (PodSpec) SwaggerDoc() map[string]string { var map_PodStatus = map[string]string{ "": "PodStatus represents information about the status of a pod. Status may trail the actual state of a system, especially if the node that hosts the pod cannot contact the control plane.", + "observedGeneration": "If set, this represents the .metadata.generation that the pod status was set based upon. This is an alpha field. Enable PodObservedGenerationTracking to be able to use this field.", "phase": "The phase of a Pod is a simple, high-level summary of where the Pod is in its lifecycle. The conditions array, the reason and message fields, and the individual container status arrays contain more detail about the pod's status. There are five possible phase values:\n\nPending: The pod has been accepted by the Kubernetes system, but one or more of the container images has not been created. This includes time before being scheduled as well as time spent downloading images over the network, which could take a while. Running: The pod has been bound to a node, and all of the containers have been created. At least one container is still running, or is in the process of starting or restarting. Succeeded: All containers in the pod have terminated in success, and will not be restarted. Failed: All containers in the pod have terminated, and at least one container has terminated in failure. The container either exited with non-zero status or was terminated by the system. Unknown: For some reason the state of the pod could not be obtained, typically due to an error in communicating with the host of the pod.\n\nMore info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-phase", "conditions": "Current service state of pod. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-conditions", "message": "A human readable message indicating details about why the pod is in this condition.", @@ -1860,7 +1874,7 @@ var map_PodStatus = map[string]string{ "containerStatuses": "Statuses of containers in this pod. Each container in the pod should have at most one status in this list, and all statuses should be for containers in the pod. However this is not enforced. If a status for a non-existent container is present in the list, or the list has duplicate names, the behavior of various Kubernetes components is not defined and those statuses might be ignored. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-and-container-status", "qosClass": "The Quality of Service (QOS) classification assigned to the pod based on resource requirements See PodQOSClass type for available QOS classes More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-qos/#quality-of-service-classes", "ephemeralContainerStatuses": "Statuses for any ephemeral containers that have run in this pod. Each ephemeral container in the pod should have at most one status in this list, and all statuses should be for containers in the pod. However this is not enforced. If a status for a non-existent container is present in the list, or the list has duplicate names, the behavior of various Kubernetes components is not defined and those statuses might be ignored. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-and-container-status", - "resize": "Status of resources resize desired for pod's containers. It is empty if no resources resize is pending. Any changes to container resources will automatically set this to \"Proposed\"", + "resize": "Status of resources resize desired for pod's containers. It is empty if no resources resize is pending. Any changes to container resources will automatically set this to \"Proposed\" Deprecated: Resize status is moved to two pod conditions PodResizePending and PodResizeInProgress. PodResizePending will track states where the spec has been resized, but the Kubelet has not yet allocated the resources. PodResizeInProgress will track in-progress resizes, and should be present whenever allocated resources != acknowledged resources.", "resourceClaimStatuses": "Status of resource claims.", } @@ -2487,7 +2501,7 @@ var map_ServiceSpec = map[string]string{ "allocateLoadBalancerNodePorts": "allocateLoadBalancerNodePorts defines if NodePorts will be automatically allocated for services with type LoadBalancer. Default is \"true\". It may be set to \"false\" if the cluster load-balancer does not rely on NodePorts. If the caller requests specific NodePorts (by specifying a value), those requests will be respected, regardless of this field. This field may only be set for services with type LoadBalancer and will be cleared if the type is changed to any other type.", "loadBalancerClass": "loadBalancerClass is the class of the load balancer implementation this Service belongs to. If specified, the value of this field must be a label-style identifier, with an optional prefix, e.g. \"internal-vip\" or \"example.com/internal-vip\". Unprefixed names are reserved for end-users. This field can only be set when the Service type is 'LoadBalancer'. If not set, the default load balancer implementation is used, today this is typically done through the cloud provider integration, but should apply for any default implementation. If set, it is assumed that a load balancer implementation is watching for Services with a matching class. Any default load balancer implementation (e.g. cloud providers) should ignore Services that set this field. This field can only be set when creating or updating a Service to type 'LoadBalancer'. Once set, it can not be changed. This field will be wiped when a service is updated to a non 'LoadBalancer' type.", "internalTrafficPolicy": "InternalTrafficPolicy describes how nodes distribute service traffic they receive on the ClusterIP. If set to \"Local\", the proxy will assume that pods only want to talk to endpoints of the service on the same node as the pod, dropping the traffic if there are no local endpoints. The default value, \"Cluster\", uses the standard behavior of routing to all endpoints evenly (possibly modified by topology and other features).", - "trafficDistribution": "TrafficDistribution offers a way to express preferences for how traffic is distributed to Service endpoints. Implementations can use this field as a hint, but are not required to guarantee strict adherence. If the field is not set, the implementation will apply its default routing strategy. If set to \"PreferClose\", implementations should prioritize endpoints that are topologically close (e.g., same zone). This is a beta field and requires enabling ServiceTrafficDistribution feature.", + "trafficDistribution": "TrafficDistribution offers a way to express preferences for how traffic is distributed to Service endpoints. Implementations can use this field as a hint, but are not required to guarantee strict adherence. If the field is not set, the implementation will apply its default routing strategy. If set to \"PreferClose\", implementations should prioritize endpoints that are in the same zone.", } func (ServiceSpec) SwaggerDoc() map[string]string { @@ -2619,8 +2633,8 @@ var map_TopologySpreadConstraint = map[string]string{ "whenUnsatisfiable": "WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy the spread constraint. - DoNotSchedule (default) tells the scheduler not to schedule it. - ScheduleAnyway tells the scheduler to schedule the pod in any location,\n but giving higher precedence to topologies that would help reduce the\n skew.\nA constraint is considered \"Unsatisfiable\" for an incoming pod if and only if every possible node assignment for that pod would violate \"MaxSkew\" on some topology. For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same labelSelector spread as 3/1/1: ", "labelSelector": "LabelSelector is used to find matching pods. Pods that match this label selector are counted to determine the number of pods in their corresponding topology domain.", "minDomains": "MinDomains indicates a minimum number of eligible domains. When the number of eligible domains with matching topology keys is less than minDomains, Pod Topology Spread treats \"global minimum\" as 0, and then the calculation of Skew is performed. And when the number of eligible domains with matching topology keys equals or greater than minDomains, this value has no effect on scheduling. As a result, when the number of eligible domains is less than minDomains, scheduler won't schedule more than maxSkew Pods to those domains. If value is nil, the constraint behaves as if MinDomains is equal to 1. Valid values are integers greater than 0. When value is not nil, WhenUnsatisfiable must be DoNotSchedule.\n\nFor example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same labelSelector spread as 2/2/2: ", - "nodeAffinityPolicy": "NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector when calculating pod topology spread skew. Options are: - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations.\n\nIf this value is nil, the behavior is equivalent to the Honor policy. This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag.", - "nodeTaintsPolicy": "NodeTaintsPolicy indicates how we will treat node taints when calculating pod topology spread skew. Options are: - Honor: nodes without taints, along with tainted nodes for which the incoming pod has a toleration, are included. - Ignore: node taints are ignored. All nodes are included.\n\nIf this value is nil, the behavior is equivalent to the Ignore policy. This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag.", + "nodeAffinityPolicy": "NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector when calculating pod topology spread skew. Options are: - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations.\n\nIf this value is nil, the behavior is equivalent to the Honor policy.", + "nodeTaintsPolicy": "NodeTaintsPolicy indicates how we will treat node taints when calculating pod topology spread skew. Options are: - Honor: nodes without taints, along with tainted nodes for which the incoming pod has a toleration, are included. - Ignore: node taints are ignored. All nodes are included.\n\nIf this value is nil, the behavior is equivalent to the Ignore policy.", "matchLabelKeys": "MatchLabelKeys is a set of pod label keys to select the pods over which spreading will be calculated. The keys are used to lookup values from the incoming pod labels, those key-value labels are ANDed with labelSelector to select the group of existing pods over which spreading will be calculated for the incoming pod. The same key is forbidden to exist in both MatchLabelKeys and LabelSelector. MatchLabelKeys cannot be set when LabelSelector isn't set. Keys that don't exist in the incoming pod labels will be ignored. A null or empty list means only match against labelSelector.\n\nThis is a beta field and requires the MatchLabelKeysInPodTopologySpread feature gate to be enabled (enabled by default).", } @@ -2760,7 +2774,7 @@ var map_VolumeSource = map[string]string{ "storageos": "storageOS represents a StorageOS volume attached and mounted on Kubernetes nodes. Deprecated: StorageOS is deprecated and the in-tree storageos type is no longer supported.", "csi": "csi (Container Storage Interface) represents ephemeral storage that is handled by certain external CSI drivers.", "ephemeral": "ephemeral represents a volume that is handled by a cluster storage driver. The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, and deleted when the pod is removed.\n\nUse this if: a) the volume is only needed while the pod runs, b) features of normal volumes like restoring from snapshot or capacity\n tracking are needed,\nc) the storage driver is specified through a storage class, and d) the storage driver supports dynamic volume provisioning through\n a PersistentVolumeClaim (see EphemeralVolumeSource for more\n information on the connection between this volume type\n and PersistentVolumeClaim).\n\nUse PersistentVolumeClaim or one of the vendor-specific APIs for volumes that persist for longer than the lifecycle of an individual pod.\n\nUse CSI for light-weight local ephemeral volumes if the CSI driver is meant to be used that way - see the documentation of the driver for more information.\n\nA pod can use both types of ephemeral volumes and persistent volumes at the same time.", - "image": "image represents an OCI object (a container image or artifact) pulled and mounted on the kubelet's host machine. The volume is resolved at pod startup depending on which PullPolicy value is provided:\n\n- Always: the kubelet always attempts to pull the reference. Container creation will fail If the pull fails. - Never: the kubelet never pulls the reference and only uses a local image or artifact. Container creation will fail if the reference isn't present. - IfNotPresent: the kubelet pulls if the reference isn't already present on disk. Container creation will fail if the reference isn't present and the pull fails.\n\nThe volume gets re-resolved if the pod gets deleted and recreated, which means that new remote content will become available on pod recreation. A failure to resolve or pull the image during pod startup will block containers from starting and may add significant latency. Failures will be retried using normal volume backoff and will be reported on the pod reason and message. The types of objects that may be mounted by this volume are defined by the container runtime implementation on a host machine and at minimum must include all valid types supported by the container image field. The OCI object gets mounted in a single directory (spec.containers[*].volumeMounts.mountPath) by merging the manifest layers in the same way as for container images. The volume will be mounted read-only (ro) and non-executable files (noexec). Sub path mounts for containers are not supported (spec.containers[*].volumeMounts.subpath). The field spec.securityContext.fsGroupChangePolicy has no effect on this volume type.", + "image": "image represents an OCI object (a container image or artifact) pulled and mounted on the kubelet's host machine. The volume is resolved at pod startup depending on which PullPolicy value is provided:\n\n- Always: the kubelet always attempts to pull the reference. Container creation will fail If the pull fails. - Never: the kubelet never pulls the reference and only uses a local image or artifact. Container creation will fail if the reference isn't present. - IfNotPresent: the kubelet pulls if the reference isn't already present on disk. Container creation will fail if the reference isn't present and the pull fails.\n\nThe volume gets re-resolved if the pod gets deleted and recreated, which means that new remote content will become available on pod recreation. A failure to resolve or pull the image during pod startup will block containers from starting and may add significant latency. Failures will be retried using normal volume backoff and will be reported on the pod reason and message. The types of objects that may be mounted by this volume are defined by the container runtime implementation on a host machine and at minimum must include all valid types supported by the container image field. The OCI object gets mounted in a single directory (spec.containers[*].volumeMounts.mountPath) by merging the manifest layers in the same way as for container images. The volume will be mounted read-only (ro) and non-executable files (noexec). Sub path mounts for containers are not supported (spec.containers[*].volumeMounts.subpath) before 1.33. The field spec.securityContext.fsGroupChangePolicy has no effect on this volume type.", } func (VolumeSource) SwaggerDoc() map[string]string { diff --git a/go-controller/vendor/k8s.io/api/core/v1/zz_generated.deepcopy.go b/go-controller/vendor/k8s.io/api/core/v1/zz_generated.deepcopy.go index 3f669092ef..619c525427 100644 --- a/go-controller/vendor/k8s.io/api/core/v1/zz_generated.deepcopy.go +++ b/go-controller/vendor/k8s.io/api/core/v1/zz_generated.deepcopy.go @@ -1055,6 +1055,11 @@ func (in *ContainerStatus) DeepCopyInto(out *ContainerStatus) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.StopSignal != nil { + in, out := &in.StopSignal, &out.StopSignal + *out = new(Signal) + **out = **in + } return } @@ -2101,6 +2106,11 @@ func (in *Lifecycle) DeepCopyInto(out *Lifecycle) { *out = new(LifecycleHandler) (*in).DeepCopyInto(*out) } + if in.StopSignal != nil { + in, out := &in.StopSignal, &out.StopSignal + *out = new(Signal) + **out = **in + } return } @@ -3002,7 +3012,7 @@ func (in *NodeStatus) DeepCopyInto(out *NodeStatus) { copy(*out, *in) } out.DaemonEndpoints = in.DaemonEndpoints - out.NodeInfo = in.NodeInfo + in.NodeInfo.DeepCopyInto(&out.NodeInfo) if in.Images != nil { in, out := &in.Images, &out.Images *out = make([]ContainerImage, len(*in)) @@ -3050,9 +3060,35 @@ func (in *NodeStatus) DeepCopy() *NodeStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeSwapStatus) DeepCopyInto(out *NodeSwapStatus) { + *out = *in + if in.Capacity != nil { + in, out := &in.Capacity, &out.Capacity + *out = new(int64) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeSwapStatus. +func (in *NodeSwapStatus) DeepCopy() *NodeSwapStatus { + if in == nil { + return nil + } + out := new(NodeSwapStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NodeSystemInfo) DeepCopyInto(out *NodeSystemInfo) { *out = *in + if in.Swap != nil { + in, out := &in.Swap, &out.Swap + *out = new(NodeSwapStatus) + (*in).DeepCopyInto(*out) + } return } diff --git a/go-controller/vendor/k8s.io/api/discovery/v1/doc.go b/go-controller/vendor/k8s.io/api/discovery/v1/doc.go index 01913669ff..43e30b7f43 100644 --- a/go-controller/vendor/k8s.io/api/discovery/v1/doc.go +++ b/go-controller/vendor/k8s.io/api/discovery/v1/doc.go @@ -20,4 +20,4 @@ limitations under the License. // +k8s:prerelease-lifecycle-gen=true // +groupName=discovery.k8s.io -package v1 // import "k8s.io/api/discovery/v1" +package v1 diff --git a/go-controller/vendor/k8s.io/api/discovery/v1/generated.pb.go b/go-controller/vendor/k8s.io/api/discovery/v1/generated.pb.go index 5792481dc1..443ff8f8f3 100644 --- a/go-controller/vendor/k8s.io/api/discovery/v1/generated.pb.go +++ b/go-controller/vendor/k8s.io/api/discovery/v1/generated.pb.go @@ -214,10 +214,38 @@ func (m *EndpointSliceList) XXX_DiscardUnknown() { var xxx_messageInfo_EndpointSliceList proto.InternalMessageInfo +func (m *ForNode) Reset() { *m = ForNode{} } +func (*ForNode) ProtoMessage() {} +func (*ForNode) Descriptor() ([]byte, []int) { + return fileDescriptor_2237b452324cf77e, []int{6} +} +func (m *ForNode) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ForNode) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ForNode) XXX_Merge(src proto.Message) { + xxx_messageInfo_ForNode.Merge(m, src) +} +func (m *ForNode) XXX_Size() int { + return m.Size() +} +func (m *ForNode) XXX_DiscardUnknown() { + xxx_messageInfo_ForNode.DiscardUnknown(m) +} + +var xxx_messageInfo_ForNode proto.InternalMessageInfo + func (m *ForZone) Reset() { *m = ForZone{} } func (*ForZone) ProtoMessage() {} func (*ForZone) Descriptor() ([]byte, []int) { - return fileDescriptor_2237b452324cf77e, []int{6} + return fileDescriptor_2237b452324cf77e, []int{7} } func (m *ForZone) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -250,6 +278,7 @@ func init() { proto.RegisterType((*EndpointPort)(nil), "k8s.io.api.discovery.v1.EndpointPort") proto.RegisterType((*EndpointSlice)(nil), "k8s.io.api.discovery.v1.EndpointSlice") proto.RegisterType((*EndpointSliceList)(nil), "k8s.io.api.discovery.v1.EndpointSliceList") + proto.RegisterType((*ForNode)(nil), "k8s.io.api.discovery.v1.ForNode") proto.RegisterType((*ForZone)(nil), "k8s.io.api.discovery.v1.ForZone") } @@ -258,62 +287,64 @@ func init() { } var fileDescriptor_2237b452324cf77e = []byte{ - // 877 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x55, 0x4d, 0x6f, 0xdc, 0x44, - 0x18, 0x5e, 0x67, 0x63, 0x62, 0x8f, 0x13, 0xd1, 0x8e, 0x90, 0x62, 0x2d, 0xc8, 0x5e, 0x8c, 0x0a, - 0x2b, 0x45, 0x78, 0x49, 0x84, 0x50, 0x41, 0xe2, 0x10, 0xd3, 0xd0, 0xf2, 0x15, 0xa2, 0x69, 0x4e, - 0x15, 0x52, 0x71, 0xec, 0x37, 0x5e, 0x93, 0xd8, 0x63, 0x79, 0x26, 0x2b, 0x2d, 0x27, 0x2e, 0x9c, - 0xe1, 0x17, 0x71, 0x44, 0x39, 0xf6, 0x46, 0x4f, 0x16, 0x31, 0x7f, 0x81, 0x53, 0x4f, 0x68, 0xc6, - 0x9f, 0x61, 0xb3, 0xda, 0xde, 0x3c, 0xcf, 0x3c, 0xcf, 0xfb, 0xf1, 0xcc, 0xcc, 0x6b, 0xf4, 0xc1, - 0xc5, 0x43, 0xe6, 0xc6, 0x74, 0xea, 0x67, 0xf1, 0x34, 0x8c, 0x59, 0x40, 0xe7, 0x90, 0x2f, 0xa6, - 0xf3, 0xfd, 0x69, 0x04, 0x29, 0xe4, 0x3e, 0x87, 0xd0, 0xcd, 0x72, 0xca, 0x29, 0xde, 0xad, 0x88, - 0xae, 0x9f, 0xc5, 0x6e, 0x4b, 0x74, 0xe7, 0xfb, 0xa3, 0x0f, 0xa3, 0x98, 0xcf, 0xae, 0xce, 0xdc, - 0x80, 0x26, 0xd3, 0x88, 0x46, 0x74, 0x2a, 0xf9, 0x67, 0x57, 0xe7, 0x72, 0x25, 0x17, 0xf2, 0xab, - 0x8a, 0x33, 0x72, 0x7a, 0x09, 0x03, 0x9a, 0xc3, 0x1d, 0xb9, 0x46, 0x1f, 0x77, 0x9c, 0xc4, 0x0f, - 0x66, 0x71, 0x2a, 0x6a, 0xca, 0x2e, 0x22, 0x01, 0xb0, 0x69, 0x02, 0xdc, 0xbf, 0x4b, 0x35, 0x5d, - 0xa5, 0xca, 0xaf, 0x52, 0x1e, 0x27, 0xb0, 0x24, 0xf8, 0x64, 0x9d, 0x80, 0x05, 0x33, 0x48, 0xfc, - 0xff, 0xeb, 0x9c, 0x7f, 0x37, 0x91, 0x76, 0x94, 0x86, 0x19, 0x8d, 0x53, 0x8e, 0xf7, 0x90, 0xee, - 0x87, 0x61, 0x0e, 0x8c, 0x01, 0x33, 0x95, 0xf1, 0x70, 0xa2, 0x7b, 0x3b, 0x65, 0x61, 0xeb, 0x87, - 0x0d, 0x48, 0xba, 0x7d, 0xfc, 0x1c, 0xa1, 0x80, 0xa6, 0x61, 0xcc, 0x63, 0x9a, 0x32, 0x73, 0x63, - 0xac, 0x4c, 0x8c, 0x83, 0x3d, 0x77, 0x85, 0xb3, 0x6e, 0x93, 0xe3, 0x8b, 0x56, 0xe2, 0xe1, 0xeb, - 0xc2, 0x1e, 0x94, 0x85, 0x8d, 0x3a, 0x8c, 0xf4, 0x42, 0xe2, 0x09, 0xd2, 0x66, 0x94, 0xf1, 0xd4, - 0x4f, 0xc0, 0x1c, 0x8e, 0x95, 0x89, 0xee, 0x6d, 0x97, 0x85, 0xad, 0x3d, 0xa9, 0x31, 0xd2, 0xee, - 0xe2, 0x13, 0xa4, 0x73, 0x3f, 0x8f, 0x80, 0x13, 0x38, 0x37, 0x37, 0x65, 0x25, 0xef, 0xf5, 0x2b, - 0x11, 0x67, 0x23, 0x8a, 0xf8, 0xfe, 0xec, 0x27, 0x08, 0x04, 0x09, 0x72, 0x48, 0x03, 0xa8, 0x9a, - 0x3b, 0x6d, 0x94, 0xa4, 0x0b, 0x82, 0x7f, 0x55, 0x10, 0x0e, 0x21, 0xcb, 0x21, 0x10, 0x5e, 0x9d, - 0xd2, 0x8c, 0x5e, 0xd2, 0x68, 0x61, 0xaa, 0xe3, 0xe1, 0xc4, 0x38, 0xf8, 0x74, 0x6d, 0x97, 0xee, - 0xa3, 0x25, 0xed, 0x51, 0xca, 0xf3, 0x85, 0x37, 0xaa, 0x7b, 0xc6, 0xcb, 0x04, 0x72, 0x47, 0x42, - 0xe1, 0x41, 0x4a, 0x43, 0x38, 0x16, 0x1e, 0xbc, 0xd1, 0x79, 0x70, 0x5c, 0x63, 0xa4, 0xdd, 0xc5, - 0xef, 0xa0, 0xcd, 0x9f, 0x69, 0x0a, 0xe6, 0x96, 0x64, 0x69, 0x65, 0x61, 0x6f, 0x3e, 0xa3, 0x29, - 0x10, 0x89, 0xe2, 0xc7, 0x48, 0x9d, 0xc5, 0x29, 0x67, 0xa6, 0x26, 0xdd, 0x79, 0x7f, 0x6d, 0x07, - 0x4f, 0x04, 0xdb, 0xd3, 0xcb, 0xc2, 0x56, 0xe5, 0x27, 0xa9, 0xf4, 0xa3, 0x23, 0xb4, 0xbb, 0xa2, - 0x37, 0x7c, 0x0f, 0x0d, 0x2f, 0x60, 0x61, 0x2a, 0xa2, 0x00, 0x22, 0x3e, 0xf1, 0x5b, 0x48, 0x9d, - 0xfb, 0x97, 0x57, 0x20, 0x6f, 0x87, 0x4e, 0xaa, 0xc5, 0x67, 0x1b, 0x0f, 0x15, 0xe7, 0x37, 0x05, - 0xe1, 0xe5, 0x2b, 0x81, 0x6d, 0xa4, 0xe6, 0xe0, 0x87, 0x55, 0x10, 0xad, 0x4a, 0x4f, 0x04, 0x40, - 0x2a, 0x1c, 0x3f, 0x40, 0x5b, 0x0c, 0xf2, 0x79, 0x9c, 0x46, 0x32, 0xa6, 0xe6, 0x19, 0x65, 0x61, - 0x6f, 0x3d, 0xad, 0x20, 0xd2, 0xec, 0xe1, 0x7d, 0x64, 0x70, 0xc8, 0x93, 0x38, 0xf5, 0xb9, 0xa0, - 0x0e, 0x25, 0xf5, 0xcd, 0xb2, 0xb0, 0x8d, 0xd3, 0x0e, 0x26, 0x7d, 0x8e, 0xf3, 0x1c, 0xed, 0xdc, - 0xea, 0x1d, 0x1f, 0x23, 0xed, 0x9c, 0xe6, 0xc2, 0xc3, 0xea, 0x2d, 0x18, 0x07, 0xe3, 0x95, 0xae, - 0x7d, 0x59, 0x11, 0xbd, 0x7b, 0xf5, 0xf1, 0x6a, 0x35, 0xc0, 0x48, 0x1b, 0xc3, 0xf9, 0x53, 0x41, - 0xdb, 0x4d, 0x86, 0x13, 0x9a, 0x73, 0x71, 0x62, 0xf2, 0x6e, 0x2b, 0xdd, 0x89, 0xc9, 0x33, 0x95, - 0x28, 0x7e, 0x8c, 0x34, 0xf9, 0x42, 0x03, 0x7a, 0x59, 0xd9, 0xe7, 0xed, 0x89, 0xc0, 0x27, 0x35, - 0xf6, 0xaa, 0xb0, 0xdf, 0x5e, 0x9e, 0x3e, 0x6e, 0xb3, 0x4d, 0x5a, 0xb1, 0x48, 0x93, 0xd1, 0x9c, - 0x4b, 0x13, 0xd4, 0x2a, 0x8d, 0x48, 0x4f, 0x24, 0x2a, 0x9c, 0xf2, 0xb3, 0xac, 0x91, 0xc9, 0xc7, - 0xa3, 0x57, 0x4e, 0x1d, 0x76, 0x30, 0xe9, 0x73, 0x9c, 0xbf, 0x36, 0x3a, 0xab, 0x9e, 0x5e, 0xc6, - 0x01, 0xe0, 0x1f, 0x91, 0x26, 0x06, 0x59, 0xe8, 0x73, 0x5f, 0x76, 0x63, 0x1c, 0x7c, 0xd4, 0xb3, - 0xaa, 0x9d, 0x47, 0x6e, 0x76, 0x11, 0x09, 0x80, 0xb9, 0x82, 0xdd, 0x3d, 0xc8, 0xef, 0x80, 0xfb, - 0xdd, 0x34, 0xe8, 0x30, 0xd2, 0x46, 0xc5, 0x8f, 0x90, 0x51, 0x4f, 0x9e, 0xd3, 0x45, 0x06, 0x75, - 0x99, 0x4e, 0x2d, 0x31, 0x0e, 0xbb, 0xad, 0x57, 0xb7, 0x97, 0xa4, 0x2f, 0xc3, 0x04, 0xe9, 0x50, - 0x17, 0x2e, 0x26, 0x96, 0x38, 0xd3, 0x77, 0xd7, 0xbe, 0x04, 0xef, 0x7e, 0x9d, 0x46, 0x6f, 0x10, - 0x46, 0xba, 0x30, 0xf8, 0x6b, 0xa4, 0x0a, 0x23, 0x99, 0x39, 0x94, 0xf1, 0x1e, 0xac, 0x8d, 0x27, - 0xcc, 0xf7, 0x76, 0xea, 0x98, 0xaa, 0x58, 0x31, 0x52, 0x85, 0x70, 0xfe, 0x50, 0xd0, 0xfd, 0x5b, - 0xce, 0x7e, 0x1b, 0x33, 0x8e, 0x7f, 0x58, 0x72, 0xd7, 0x7d, 0x3d, 0x77, 0x85, 0x5a, 0x7a, 0xdb, - 0x5e, 0xcb, 0x06, 0xe9, 0x39, 0xfb, 0x0d, 0x52, 0x63, 0x0e, 0x49, 0xe3, 0xc7, 0xfa, 0xc9, 0x20, - 0x0b, 0xeb, 0x1a, 0xf8, 0x4a, 0x88, 0x49, 0x15, 0xc3, 0xd9, 0x43, 0x5b, 0xf5, 0xcd, 0xc7, 0xe3, - 0x5b, 0xb7, 0x7b, 0xbb, 0xa6, 0xf7, 0x6e, 0xb8, 0xf7, 0xf9, 0xf5, 0x8d, 0x35, 0x78, 0x71, 0x63, - 0x0d, 0x5e, 0xde, 0x58, 0x83, 0x5f, 0x4a, 0x4b, 0xb9, 0x2e, 0x2d, 0xe5, 0x45, 0x69, 0x29, 0x2f, - 0x4b, 0x4b, 0xf9, 0xbb, 0xb4, 0x94, 0xdf, 0xff, 0xb1, 0x06, 0xcf, 0x76, 0x57, 0xfc, 0xd4, 0xff, - 0x0b, 0x00, 0x00, 0xff, 0xff, 0x76, 0x4b, 0x26, 0xe3, 0xee, 0x07, 0x00, 0x00, + // 902 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x56, 0xcf, 0x6f, 0xe3, 0x44, + 0x14, 0x8e, 0x9b, 0x9a, 0xda, 0xe3, 0x56, 0xec, 0x8e, 0x90, 0x6a, 0x05, 0x64, 0x07, 0xa3, 0x85, + 0x48, 0x15, 0x0e, 0xad, 0x10, 0x5a, 0x90, 0x38, 0xd4, 0x6c, 0xd9, 0xe5, 0x57, 0xa9, 0x66, 0x7b, + 0x5a, 0x21, 0x81, 0x6b, 0xbf, 0x3a, 0xa6, 0x8d, 0xc7, 0xf2, 0x4c, 0x22, 0x85, 0x13, 0x17, 0xce, + 0xf0, 0x9f, 0xf0, 0x1f, 0x70, 0x44, 0x3d, 0xee, 0x8d, 0x3d, 0x59, 0xd4, 0xfc, 0x0b, 0x9c, 0xf6, + 0x84, 0x66, 0xfc, 0x33, 0xa4, 0x51, 0xf6, 0xe6, 0xf9, 0xe6, 0x7b, 0xdf, 0x7b, 0xf3, 0xcd, 0x7b, + 0x23, 0xa3, 0xf7, 0xae, 0x1e, 0x32, 0x37, 0xa6, 0x63, 0x3f, 0x8d, 0xc7, 0x61, 0xcc, 0x02, 0x3a, + 0x87, 0x6c, 0x31, 0x9e, 0x1f, 0x8e, 0x23, 0x48, 0x20, 0xf3, 0x39, 0x84, 0x6e, 0x9a, 0x51, 0x4e, + 0xf1, 0x7e, 0x49, 0x74, 0xfd, 0x34, 0x76, 0x1b, 0xa2, 0x3b, 0x3f, 0x1c, 0xbc, 0x1f, 0xc5, 0x7c, + 0x32, 0xbb, 0x70, 0x03, 0x3a, 0x1d, 0x47, 0x34, 0xa2, 0x63, 0xc9, 0xbf, 0x98, 0x5d, 0xca, 0x95, + 0x5c, 0xc8, 0xaf, 0x52, 0x67, 0xe0, 0x74, 0x12, 0x06, 0x34, 0x83, 0x3b, 0x72, 0x0d, 0x3e, 0x6c, + 0x39, 0x53, 0x3f, 0x98, 0xc4, 0x89, 0xa8, 0x29, 0xbd, 0x8a, 0x04, 0xc0, 0xc6, 0x53, 0xe0, 0xfe, + 0x5d, 0x51, 0xe3, 0x75, 0x51, 0xd9, 0x2c, 0xe1, 0xf1, 0x14, 0x56, 0x02, 0x3e, 0xda, 0x14, 0xc0, + 0x82, 0x09, 0x4c, 0xfd, 0xff, 0xc7, 0x39, 0xff, 0x6e, 0x23, 0xed, 0x24, 0x09, 0x53, 0x1a, 0x27, + 0x1c, 0x1f, 0x20, 0xdd, 0x0f, 0xc3, 0x0c, 0x18, 0x03, 0x66, 0x2a, 0xc3, 0xfe, 0x48, 0xf7, 0xf6, + 0x8a, 0xdc, 0xd6, 0x8f, 0x6b, 0x90, 0xb4, 0xfb, 0xf8, 0x7b, 0x84, 0x02, 0x9a, 0x84, 0x31, 0x8f, + 0x69, 0xc2, 0xcc, 0xad, 0xa1, 0x32, 0x32, 0x8e, 0x0e, 0xdc, 0x35, 0xce, 0xba, 0x75, 0x8e, 0xcf, + 0x9a, 0x10, 0x0f, 0xdf, 0xe4, 0x76, 0xaf, 0xc8, 0x6d, 0xd4, 0x62, 0xa4, 0x23, 0x89, 0x47, 0x48, + 0x9b, 0x50, 0xc6, 0x13, 0x7f, 0x0a, 0x66, 0x7f, 0xa8, 0x8c, 0x74, 0x6f, 0xb7, 0xc8, 0x6d, 0xed, + 0x49, 0x85, 0x91, 0x66, 0x17, 0x9f, 0x21, 0x9d, 0xfb, 0x59, 0x04, 0x9c, 0xc0, 0xa5, 0xb9, 0x2d, + 0x2b, 0x79, 0xa7, 0x5b, 0x89, 0xb8, 0x1b, 0x51, 0xc4, 0xb7, 0x17, 0x3f, 0x42, 0x20, 0x48, 0x90, + 0x41, 0x12, 0x40, 0x79, 0xb8, 0xf3, 0x3a, 0x92, 0xb4, 0x22, 0xf8, 0x17, 0x05, 0xe1, 0x10, 0xd2, + 0x0c, 0x02, 0xe1, 0xd5, 0x39, 0x4d, 0xe9, 0x35, 0x8d, 0x16, 0xa6, 0x3a, 0xec, 0x8f, 0x8c, 0xa3, + 0x8f, 0x37, 0x9e, 0xd2, 0x7d, 0xb4, 0x12, 0x7b, 0x92, 0xf0, 0x6c, 0xe1, 0x0d, 0xaa, 0x33, 0xe3, + 0x55, 0x02, 0xb9, 0x23, 0xa1, 0xf0, 0x20, 0xa1, 0x21, 0x9c, 0x0a, 0x0f, 0x5e, 0x6b, 0x3d, 0x38, + 0xad, 0x30, 0xd2, 0xec, 0xe2, 0xb7, 0xd0, 0xf6, 0x4f, 0x34, 0x01, 0x73, 0x47, 0xb2, 0xb4, 0x22, + 0xb7, 0xb7, 0x9f, 0xd1, 0x04, 0x88, 0x44, 0xf1, 0x63, 0xa4, 0x4e, 0xe2, 0x84, 0x33, 0x53, 0x93, + 0xee, 0xbc, 0xbb, 0xf1, 0x04, 0x4f, 0x04, 0xdb, 0xd3, 0x8b, 0xdc, 0x56, 0xe5, 0x27, 0x29, 0xe3, + 0x07, 0x27, 0x68, 0x7f, 0xcd, 0xd9, 0xf0, 0x3d, 0xd4, 0xbf, 0x82, 0x85, 0xa9, 0x88, 0x02, 0x88, + 0xf8, 0xc4, 0x6f, 0x20, 0x75, 0xee, 0x5f, 0xcf, 0x40, 0x76, 0x87, 0x4e, 0xca, 0xc5, 0x27, 0x5b, + 0x0f, 0x15, 0xe7, 0x57, 0x05, 0xe1, 0xd5, 0x96, 0xc0, 0x36, 0x52, 0x33, 0xf0, 0xc3, 0x52, 0x44, + 0x2b, 0xd3, 0x13, 0x01, 0x90, 0x12, 0xc7, 0x0f, 0xd0, 0x0e, 0x83, 0x6c, 0x1e, 0x27, 0x91, 0xd4, + 0xd4, 0x3c, 0xa3, 0xc8, 0xed, 0x9d, 0xa7, 0x25, 0x44, 0xea, 0x3d, 0x7c, 0x88, 0x0c, 0x0e, 0xd9, + 0x34, 0x4e, 0x7c, 0x2e, 0xa8, 0x7d, 0x49, 0x7d, 0xbd, 0xc8, 0x6d, 0xe3, 0xbc, 0x85, 0x49, 0x97, + 0xe3, 0xfc, 0xae, 0xa0, 0xbd, 0xa5, 0xc3, 0xe3, 0x53, 0xa4, 0x5d, 0xd2, 0x4c, 0x98, 0x58, 0x0e, + 0x83, 0x71, 0x34, 0x5c, 0x6b, 0xdb, 0xe7, 0x25, 0xd1, 0xbb, 0x57, 0xdd, 0xaf, 0x56, 0x01, 0x8c, + 0x34, 0x1a, 0x95, 0x9e, 0xb8, 0x3a, 0x31, 0x2e, 0x1b, 0xf5, 0x04, 0x71, 0x49, 0x4f, 0x46, 0x92, + 0x46, 0xc3, 0xf9, 0x53, 0x41, 0xbb, 0x75, 0xc5, 0x67, 0x34, 0xe3, 0xa2, 0x05, 0xe4, 0xb0, 0x28, + 0x6d, 0x0b, 0xc8, 0x26, 0x91, 0x28, 0x7e, 0x8c, 0x34, 0x39, 0xf2, 0x01, 0xbd, 0x2e, 0xef, 0xc3, + 0x3b, 0x10, 0xc2, 0x67, 0x15, 0xf6, 0x32, 0xb7, 0xdf, 0x5c, 0x7d, 0xce, 0xdc, 0x7a, 0x9b, 0x34, + 0xc1, 0x22, 0x4d, 0x4a, 0x33, 0x2e, 0x5d, 0x55, 0xcb, 0x34, 0x22, 0x3d, 0x91, 0xa8, 0xb0, 0xde, + 0x4f, 0xd3, 0x3a, 0x4c, 0x4e, 0xa3, 0x5e, 0x5a, 0x7f, 0xdc, 0xc2, 0xa4, 0xcb, 0x71, 0xfe, 0xda, + 0x6a, 0xad, 0x7f, 0x7a, 0x1d, 0x07, 0x80, 0x7f, 0x40, 0x9a, 0x78, 0x19, 0x43, 0x9f, 0xfb, 0xf2, + 0x34, 0xc6, 0xd1, 0x07, 0x1d, 0xab, 0x9a, 0x07, 0xce, 0x4d, 0xaf, 0x22, 0x01, 0x30, 0x57, 0xb0, + 0xdb, 0x09, 0xff, 0x06, 0xb8, 0xdf, 0x3e, 0x2f, 0x2d, 0x46, 0x1a, 0x55, 0xfc, 0x08, 0x19, 0xd5, + 0x53, 0x76, 0xbe, 0x48, 0xa1, 0x2a, 0xd3, 0xa9, 0x42, 0x8c, 0xe3, 0x76, 0xeb, 0xe5, 0xf2, 0x92, + 0x74, 0xc3, 0x30, 0x41, 0x3a, 0x54, 0x85, 0xd7, 0x77, 0xfa, 0xf6, 0xc6, 0xd1, 0xf2, 0xee, 0x57, + 0x69, 0xf4, 0x1a, 0x61, 0xa4, 0x95, 0xc1, 0x5f, 0x22, 0x55, 0x18, 0xc9, 0xcc, 0xbe, 0xd4, 0x7b, + 0xb0, 0x51, 0x4f, 0x98, 0xef, 0xed, 0x55, 0x9a, 0xaa, 0x58, 0x31, 0x52, 0x4a, 0x38, 0x7f, 0x28, + 0xe8, 0xfe, 0x92, 0xb3, 0x5f, 0xc7, 0x8c, 0xe3, 0xef, 0x56, 0xdc, 0x75, 0x5f, 0xcd, 0x5d, 0x11, + 0x2d, 0xbd, 0x6d, 0xda, 0xb2, 0x46, 0x3a, 0xce, 0x7e, 0x85, 0xd4, 0x98, 0xc3, 0xb4, 0xf6, 0x63, + 0xf3, 0x53, 0x23, 0x0b, 0x6b, 0x0f, 0xf0, 0x85, 0x08, 0x26, 0xa5, 0x86, 0x73, 0x80, 0x76, 0xaa, + 0xce, 0xc7, 0xc3, 0xa5, 0xee, 0xde, 0xad, 0xe8, 0x9d, 0x0e, 0xaf, 0xc8, 0x62, 0xd8, 0x36, 0x93, + 0xbd, 0x4f, 0x6f, 0x6e, 0xad, 0xde, 0xf3, 0x5b, 0xab, 0xf7, 0xe2, 0xd6, 0xea, 0xfd, 0x5c, 0x58, + 0xca, 0x4d, 0x61, 0x29, 0xcf, 0x0b, 0x4b, 0x79, 0x51, 0x58, 0xca, 0xdf, 0x85, 0xa5, 0xfc, 0xf6, + 0x8f, 0xd5, 0x7b, 0xb6, 0xbf, 0xe6, 0x97, 0xe2, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf4, 0xfc, + 0xbe, 0xad, 0x6c, 0x08, 0x00, 0x00, } func (m *Endpoint) Marshal() (dAtA []byte, err error) { @@ -500,6 +531,20 @@ func (m *EndpointHints) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.ForNodes) > 0 { + for iNdEx := len(m.ForNodes) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ForNodes[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } if len(m.ForZones) > 0 { for iNdEx := len(m.ForZones) - 1; iNdEx >= 0; iNdEx-- { { @@ -679,6 +724,34 @@ func (m *EndpointSliceList) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *ForNode) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ForNode) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ForNode) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *ForZone) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -793,6 +866,12 @@ func (m *EndpointHints) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) } } + if len(m.ForNodes) > 0 { + for _, e := range m.ForNodes { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } return n } @@ -862,6 +941,17 @@ func (m *EndpointSliceList) Size() (n int) { return n } +func (m *ForNode) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + func (m *ForZone) Size() (n int) { if m == nil { return 0 @@ -927,8 +1017,14 @@ func (this *EndpointHints) String() string { repeatedStringForForZones += strings.Replace(strings.Replace(f.String(), "ForZone", "ForZone", 1), `&`, ``, 1) + "," } repeatedStringForForZones += "}" + repeatedStringForForNodes := "[]ForNode{" + for _, f := range this.ForNodes { + repeatedStringForForNodes += strings.Replace(strings.Replace(f.String(), "ForNode", "ForNode", 1), `&`, ``, 1) + "," + } + repeatedStringForForNodes += "}" s := strings.Join([]string{`&EndpointHints{`, `ForZones:` + repeatedStringForForZones + `,`, + `ForNodes:` + repeatedStringForForNodes + `,`, `}`, }, "") return s @@ -985,6 +1081,16 @@ func (this *EndpointSliceList) String() string { }, "") return s } +func (this *ForNode) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ForNode{`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `}`, + }, "") + return s +} func (this *ForZone) String() string { if this == nil { return "nil" @@ -1592,6 +1698,40 @@ func (m *EndpointHints) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ForNodes", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ForNodes = append(m.ForNodes, ForNode{}) + if err := m.ForNodes[len(m.ForNodes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -2082,6 +2222,88 @@ func (m *EndpointSliceList) Unmarshal(dAtA []byte) error { } return nil } +func (m *ForNode) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ForNode: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ForNode: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *ForZone) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/go-controller/vendor/k8s.io/api/discovery/v1/generated.proto b/go-controller/vendor/k8s.io/api/discovery/v1/generated.proto index 8ddf0dc5d3..569d8a916e 100644 --- a/go-controller/vendor/k8s.io/api/discovery/v1/generated.proto +++ b/go-controller/vendor/k8s.io/api/discovery/v1/generated.proto @@ -31,12 +31,12 @@ option go_package = "k8s.io/api/discovery/v1"; // Endpoint represents a single logical "backend" implementing a service. message Endpoint { - // addresses of this endpoint. The contents of this field are interpreted - // according to the corresponding EndpointSlice addressType field. Consumers - // must handle different types of addresses in the context of their own - // capabilities. This must contain at least one address but no more than - // 100. These are all assumed to be fungible and clients may choose to only - // use the first element. Refer to: https://issue.k8s.io/106267 + // addresses of this endpoint. For EndpointSlices of addressType "IPv4" or "IPv6", + // the values are IP addresses in canonical form. The syntax and semantics of + // other addressType values are not defined. This must contain at least one + // address but no more than 100. EndpointSlices generated by the EndpointSlice + // controller will always have exactly 1 address. No semantics are defined for + // additional addresses beyond the first, and kube-proxy does not look at them. // +listType=set repeated string addresses = 1; @@ -82,36 +82,42 @@ message Endpoint { // EndpointConditions represents the current condition of an endpoint. message EndpointConditions { - // ready indicates that this endpoint is prepared to receive traffic, + // ready indicates that this endpoint is ready to receive traffic, // according to whatever system is managing the endpoint. A nil value - // indicates an unknown state. In most cases consumers should interpret this - // unknown state as ready. For compatibility reasons, ready should never be - // "true" for terminating endpoints, except when the normal readiness - // behavior is being explicitly overridden, for example when the associated - // Service has set the publishNotReadyAddresses flag. + // should be interpreted as "true". In general, an endpoint should be + // marked ready if it is serving and not terminating, though this can + // be overridden in some cases, such as when the associated Service has + // set the publishNotReadyAddresses flag. // +optional optional bool ready = 1; - // serving is identical to ready except that it is set regardless of the - // terminating state of endpoints. This condition should be set to true for - // a ready endpoint that is terminating. If nil, consumers should defer to - // the ready condition. + // serving indicates that this endpoint is able to receive traffic, + // according to whatever system is managing the endpoint. For endpoints + // backed by pods, the EndpointSlice controller will mark the endpoint + // as serving if the pod's Ready condition is True. A nil value should be + // interpreted as "true". // +optional optional bool serving = 2; // terminating indicates that this endpoint is terminating. A nil value - // indicates an unknown state. Consumers should interpret this unknown state - // to mean that the endpoint is not terminating. + // should be interpreted as "false". // +optional optional bool terminating = 3; } // EndpointHints provides hints describing how an endpoint should be consumed. message EndpointHints { - // forZones indicates the zone(s) this endpoint should be consumed by to - // enable topology aware routing. + // forZones indicates the zone(s) this endpoint should be consumed by when + // using topology aware routing. May contain a maximum of 8 entries. // +listType=atomic repeated ForZone forZones = 1; + + // forNodes indicates the node(s) this endpoint should be consumed by when + // using topology aware routing. May contain a maximum of 8 entries. + // This is an Alpha feature and is only used when the PreferSameTrafficDistribution + // feature gate is enabled. + // +listType=atomic + repeated ForNode forNodes = 2; } // EndpointPort represents a Port used by an EndpointSlice @@ -132,8 +138,9 @@ message EndpointPort { optional string protocol = 2; // port represents the port number of the endpoint. - // If this is not specified, ports are not restricted and must be - // interpreted in the context of the specific consumer. + // If the EndpointSlice is derived from a Kubernetes service, this must be set + // to the service's target port. EndpointSlices used for other purposes may have + // a nil port. optional int32 port = 3; // The application protocol for this port. @@ -155,9 +162,12 @@ message EndpointPort { optional string appProtocol = 4; } -// EndpointSlice represents a subset of the endpoints that implement a service. -// For a given service there may be multiple EndpointSlice objects, selected by -// labels, which must be joined to produce the full set of endpoints. +// EndpointSlice represents a set of service endpoints. Most EndpointSlices are created by +// the EndpointSlice controller to represent the Pods selected by Service objects. For a +// given service there may be multiple EndpointSlice objects which must be joined to +// produce the full set of endpoints; you can find all of the slices for a given service +// by listing EndpointSlices in the service's namespace whose `kubernetes.io/service-name` +// label contains the service's name. message EndpointSlice { // Standard object's metadata. // +optional @@ -169,7 +179,10 @@ message EndpointSlice { // supported: // * IPv4: Represents an IPv4 Address. // * IPv6: Represents an IPv6 Address. - // * FQDN: Represents a Fully Qualified Domain Name. + // * FQDN: Represents a Fully Qualified Domain Name. (Deprecated) + // The EndpointSlice controller only generates, and kube-proxy only processes, + // slices of addressType "IPv4" and "IPv6". No semantics are defined for + // the "FQDN" type. optional string addressType = 4; // endpoints is a list of unique endpoints in this slice. Each slice may @@ -178,10 +191,11 @@ message EndpointSlice { repeated Endpoint endpoints = 2; // ports specifies the list of network ports exposed by each endpoint in - // this slice. Each port must have a unique name. When ports is empty, it - // indicates that there are no defined ports. When a port is defined with a - // nil port value, it indicates "all ports". Each slice may include a + // this slice. Each port must have a unique name. Each slice may include a // maximum of 100 ports. + // Services always have at least 1 port, so EndpointSlices generated by the + // EndpointSlice controller will likewise always have at least 1 port. + // EndpointSlices used for other purposes may have an empty ports list. // +optional // +listType=atomic repeated EndpointPort ports = 3; @@ -197,6 +211,12 @@ message EndpointSliceList { repeated EndpointSlice items = 2; } +// ForNode provides information about which nodes should consume this endpoint. +message ForNode { + // name represents the name of the node. + optional string name = 1; +} + // ForZone provides information about which zones should consume this endpoint. message ForZone { // name represents the name of the zone. diff --git a/go-controller/vendor/k8s.io/api/discovery/v1/types.go b/go-controller/vendor/k8s.io/api/discovery/v1/types.go index d6a9d0fced..6f26953169 100644 --- a/go-controller/vendor/k8s.io/api/discovery/v1/types.go +++ b/go-controller/vendor/k8s.io/api/discovery/v1/types.go @@ -25,9 +25,12 @@ import ( // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:prerelease-lifecycle-gen:introduced=1.21 -// EndpointSlice represents a subset of the endpoints that implement a service. -// For a given service there may be multiple EndpointSlice objects, selected by -// labels, which must be joined to produce the full set of endpoints. +// EndpointSlice represents a set of service endpoints. Most EndpointSlices are created by +// the EndpointSlice controller to represent the Pods selected by Service objects. For a +// given service there may be multiple EndpointSlice objects which must be joined to +// produce the full set of endpoints; you can find all of the slices for a given service +// by listing EndpointSlices in the service's namespace whose `kubernetes.io/service-name` +// label contains the service's name. type EndpointSlice struct { metav1.TypeMeta `json:",inline"` @@ -41,7 +44,10 @@ type EndpointSlice struct { // supported: // * IPv4: Represents an IPv4 Address. // * IPv6: Represents an IPv6 Address. - // * FQDN: Represents a Fully Qualified Domain Name. + // * FQDN: Represents a Fully Qualified Domain Name. (Deprecated) + // The EndpointSlice controller only generates, and kube-proxy only processes, + // slices of addressType "IPv4" and "IPv6". No semantics are defined for + // the "FQDN" type. AddressType AddressType `json:"addressType" protobuf:"bytes,4,rep,name=addressType"` // endpoints is a list of unique endpoints in this slice. Each slice may @@ -50,10 +56,11 @@ type EndpointSlice struct { Endpoints []Endpoint `json:"endpoints" protobuf:"bytes,2,rep,name=endpoints"` // ports specifies the list of network ports exposed by each endpoint in - // this slice. Each port must have a unique name. When ports is empty, it - // indicates that there are no defined ports. When a port is defined with a - // nil port value, it indicates "all ports". Each slice may include a + // this slice. Each port must have a unique name. Each slice may include a // maximum of 100 ports. + // Services always have at least 1 port, so EndpointSlices generated by the + // EndpointSlice controller will likewise always have at least 1 port. + // EndpointSlices used for other purposes may have an empty ports list. // +optional // +listType=atomic Ports []EndpointPort `json:"ports" protobuf:"bytes,3,rep,name=ports"` @@ -76,12 +83,12 @@ const ( // Endpoint represents a single logical "backend" implementing a service. type Endpoint struct { - // addresses of this endpoint. The contents of this field are interpreted - // according to the corresponding EndpointSlice addressType field. Consumers - // must handle different types of addresses in the context of their own - // capabilities. This must contain at least one address but no more than - // 100. These are all assumed to be fungible and clients may choose to only - // use the first element. Refer to: https://issue.k8s.io/106267 + // addresses of this endpoint. For EndpointSlices of addressType "IPv4" or "IPv6", + // the values are IP addresses in canonical form. The syntax and semantics of + // other addressType values are not defined. This must contain at least one + // address but no more than 100. EndpointSlices generated by the EndpointSlice + // controller will always have exactly 1 address. No semantics are defined for + // additional addresses beyond the first, and kube-proxy does not look at them. // +listType=set Addresses []string `json:"addresses" protobuf:"bytes,1,rep,name=addresses"` @@ -127,36 +134,42 @@ type Endpoint struct { // EndpointConditions represents the current condition of an endpoint. type EndpointConditions struct { - // ready indicates that this endpoint is prepared to receive traffic, + // ready indicates that this endpoint is ready to receive traffic, // according to whatever system is managing the endpoint. A nil value - // indicates an unknown state. In most cases consumers should interpret this - // unknown state as ready. For compatibility reasons, ready should never be - // "true" for terminating endpoints, except when the normal readiness - // behavior is being explicitly overridden, for example when the associated - // Service has set the publishNotReadyAddresses flag. + // should be interpreted as "true". In general, an endpoint should be + // marked ready if it is serving and not terminating, though this can + // be overridden in some cases, such as when the associated Service has + // set the publishNotReadyAddresses flag. // +optional Ready *bool `json:"ready,omitempty" protobuf:"bytes,1,name=ready"` - // serving is identical to ready except that it is set regardless of the - // terminating state of endpoints. This condition should be set to true for - // a ready endpoint that is terminating. If nil, consumers should defer to - // the ready condition. + // serving indicates that this endpoint is able to receive traffic, + // according to whatever system is managing the endpoint. For endpoints + // backed by pods, the EndpointSlice controller will mark the endpoint + // as serving if the pod's Ready condition is True. A nil value should be + // interpreted as "true". // +optional Serving *bool `json:"serving,omitempty" protobuf:"bytes,2,name=serving"` // terminating indicates that this endpoint is terminating. A nil value - // indicates an unknown state. Consumers should interpret this unknown state - // to mean that the endpoint is not terminating. + // should be interpreted as "false". // +optional Terminating *bool `json:"terminating,omitempty" protobuf:"bytes,3,name=terminating"` } // EndpointHints provides hints describing how an endpoint should be consumed. type EndpointHints struct { - // forZones indicates the zone(s) this endpoint should be consumed by to - // enable topology aware routing. + // forZones indicates the zone(s) this endpoint should be consumed by when + // using topology aware routing. May contain a maximum of 8 entries. // +listType=atomic ForZones []ForZone `json:"forZones,omitempty" protobuf:"bytes,1,name=forZones"` + + // forNodes indicates the node(s) this endpoint should be consumed by when + // using topology aware routing. May contain a maximum of 8 entries. + // This is an Alpha feature and is only used when the PreferSameTrafficDistribution + // feature gate is enabled. + // +listType=atomic + ForNodes []ForNode `json:"forNodes,omitempty" protobuf:"bytes,2,name=forNodes"` } // ForZone provides information about which zones should consume this endpoint. @@ -165,6 +178,12 @@ type ForZone struct { Name string `json:"name" protobuf:"bytes,1,name=name"` } +// ForNode provides information about which nodes should consume this endpoint. +type ForNode struct { + // name represents the name of the node. + Name string `json:"name" protobuf:"bytes,1,name=name"` +} + // EndpointPort represents a Port used by an EndpointSlice // +structType=atomic type EndpointPort struct { @@ -183,8 +202,9 @@ type EndpointPort struct { Protocol *v1.Protocol `json:"protocol,omitempty" protobuf:"bytes,2,name=protocol"` // port represents the port number of the endpoint. - // If this is not specified, ports are not restricted and must be - // interpreted in the context of the specific consumer. + // If the EndpointSlice is derived from a Kubernetes service, this must be set + // to the service's target port. EndpointSlices used for other purposes may have + // a nil port. Port *int32 `json:"port,omitempty" protobuf:"bytes,3,opt,name=port"` // The application protocol for this port. diff --git a/go-controller/vendor/k8s.io/api/discovery/v1/types_swagger_doc_generated.go b/go-controller/vendor/k8s.io/api/discovery/v1/types_swagger_doc_generated.go index 41c3060568..ac5b853b9e 100644 --- a/go-controller/vendor/k8s.io/api/discovery/v1/types_swagger_doc_generated.go +++ b/go-controller/vendor/k8s.io/api/discovery/v1/types_swagger_doc_generated.go @@ -29,7 +29,7 @@ package v1 // AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT. var map_Endpoint = map[string]string{ "": "Endpoint represents a single logical \"backend\" implementing a service.", - "addresses": "addresses of this endpoint. The contents of this field are interpreted according to the corresponding EndpointSlice addressType field. Consumers must handle different types of addresses in the context of their own capabilities. This must contain at least one address but no more than 100. These are all assumed to be fungible and clients may choose to only use the first element. Refer to: https://issue.k8s.io/106267", + "addresses": "addresses of this endpoint. For EndpointSlices of addressType \"IPv4\" or \"IPv6\", the values are IP addresses in canonical form. The syntax and semantics of other addressType values are not defined. This must contain at least one address but no more than 100. EndpointSlices generated by the EndpointSlice controller will always have exactly 1 address. No semantics are defined for additional addresses beyond the first, and kube-proxy does not look at them.", "conditions": "conditions contains information about the current status of the endpoint.", "hostname": "hostname of this endpoint. This field may be used by consumers of endpoints to distinguish endpoints from each other (e.g. in DNS names). Multiple endpoints which use the same hostname should be considered fungible (e.g. multiple A values in DNS). Must be lowercase and pass DNS Label (RFC 1123) validation.", "targetRef": "targetRef is a reference to a Kubernetes object that represents this endpoint.", @@ -45,9 +45,9 @@ func (Endpoint) SwaggerDoc() map[string]string { var map_EndpointConditions = map[string]string{ "": "EndpointConditions represents the current condition of an endpoint.", - "ready": "ready indicates that this endpoint is prepared to receive traffic, according to whatever system is managing the endpoint. A nil value indicates an unknown state. In most cases consumers should interpret this unknown state as ready. For compatibility reasons, ready should never be \"true\" for terminating endpoints, except when the normal readiness behavior is being explicitly overridden, for example when the associated Service has set the publishNotReadyAddresses flag.", - "serving": "serving is identical to ready except that it is set regardless of the terminating state of endpoints. This condition should be set to true for a ready endpoint that is terminating. If nil, consumers should defer to the ready condition.", - "terminating": "terminating indicates that this endpoint is terminating. A nil value indicates an unknown state. Consumers should interpret this unknown state to mean that the endpoint is not terminating.", + "ready": "ready indicates that this endpoint is ready to receive traffic, according to whatever system is managing the endpoint. A nil value should be interpreted as \"true\". In general, an endpoint should be marked ready if it is serving and not terminating, though this can be overridden in some cases, such as when the associated Service has set the publishNotReadyAddresses flag.", + "serving": "serving indicates that this endpoint is able to receive traffic, according to whatever system is managing the endpoint. For endpoints backed by pods, the EndpointSlice controller will mark the endpoint as serving if the pod's Ready condition is True. A nil value should be interpreted as \"true\".", + "terminating": "terminating indicates that this endpoint is terminating. A nil value should be interpreted as \"false\".", } func (EndpointConditions) SwaggerDoc() map[string]string { @@ -56,7 +56,8 @@ func (EndpointConditions) SwaggerDoc() map[string]string { var map_EndpointHints = map[string]string{ "": "EndpointHints provides hints describing how an endpoint should be consumed.", - "forZones": "forZones indicates the zone(s) this endpoint should be consumed by to enable topology aware routing.", + "forZones": "forZones indicates the zone(s) this endpoint should be consumed by when using topology aware routing. May contain a maximum of 8 entries.", + "forNodes": "forNodes indicates the node(s) this endpoint should be consumed by when using topology aware routing. May contain a maximum of 8 entries. This is an Alpha feature and is only used when the PreferSameTrafficDistribution feature gate is enabled.", } func (EndpointHints) SwaggerDoc() map[string]string { @@ -67,7 +68,7 @@ var map_EndpointPort = map[string]string{ "": "EndpointPort represents a Port used by an EndpointSlice", "name": "name represents the name of this port. All ports in an EndpointSlice must have a unique name. If the EndpointSlice is derived from a Kubernetes service, this corresponds to the Service.ports[].name. Name must either be an empty string or pass DNS_LABEL validation: * must be no more than 63 characters long. * must consist of lower case alphanumeric characters or '-'. * must start and end with an alphanumeric character. Default is empty string.", "protocol": "protocol represents the IP protocol for this port. Must be UDP, TCP, or SCTP. Default is TCP.", - "port": "port represents the port number of the endpoint. If this is not specified, ports are not restricted and must be interpreted in the context of the specific consumer.", + "port": "port represents the port number of the endpoint. If the EndpointSlice is derived from a Kubernetes service, this must be set to the service's target port. EndpointSlices used for other purposes may have a nil port.", "appProtocol": "The application protocol for this port. This is used as a hint for implementations to offer richer behavior for protocols that they understand. This field follows standard Kubernetes label syntax. Valid values are either:\n\n* Un-prefixed protocol names - reserved for IANA standard service names (as per RFC-6335 and https://www.iana.org/assignments/service-names).\n\n* Kubernetes-defined prefixed names:\n * 'kubernetes.io/h2c' - HTTP/2 prior knowledge over cleartext as described in https://www.rfc-editor.org/rfc/rfc9113.html#name-starting-http-2-with-prior-\n * 'kubernetes.io/ws' - WebSocket over cleartext as described in https://www.rfc-editor.org/rfc/rfc6455\n * 'kubernetes.io/wss' - WebSocket over TLS as described in https://www.rfc-editor.org/rfc/rfc6455\n\n* Other protocols should use implementation-defined prefixed names such as mycompany.com/my-custom-protocol.", } @@ -76,11 +77,11 @@ func (EndpointPort) SwaggerDoc() map[string]string { } var map_EndpointSlice = map[string]string{ - "": "EndpointSlice represents a subset of the endpoints that implement a service. For a given service there may be multiple EndpointSlice objects, selected by labels, which must be joined to produce the full set of endpoints.", + "": "EndpointSlice represents a set of service endpoints. Most EndpointSlices are created by the EndpointSlice controller to represent the Pods selected by Service objects. For a given service there may be multiple EndpointSlice objects which must be joined to produce the full set of endpoints; you can find all of the slices for a given service by listing EndpointSlices in the service's namespace whose `kubernetes.io/service-name` label contains the service's name.", "metadata": "Standard object's metadata.", - "addressType": "addressType specifies the type of address carried by this EndpointSlice. All addresses in this slice must be the same type. This field is immutable after creation. The following address types are currently supported: * IPv4: Represents an IPv4 Address. * IPv6: Represents an IPv6 Address. * FQDN: Represents a Fully Qualified Domain Name.", + "addressType": "addressType specifies the type of address carried by this EndpointSlice. All addresses in this slice must be the same type. This field is immutable after creation. The following address types are currently supported: * IPv4: Represents an IPv4 Address. * IPv6: Represents an IPv6 Address. * FQDN: Represents a Fully Qualified Domain Name. (Deprecated) The EndpointSlice controller only generates, and kube-proxy only processes, slices of addressType \"IPv4\" and \"IPv6\". No semantics are defined for the \"FQDN\" type.", "endpoints": "endpoints is a list of unique endpoints in this slice. Each slice may include a maximum of 1000 endpoints.", - "ports": "ports specifies the list of network ports exposed by each endpoint in this slice. Each port must have a unique name. When ports is empty, it indicates that there are no defined ports. When a port is defined with a nil port value, it indicates \"all ports\". Each slice may include a maximum of 100 ports.", + "ports": "ports specifies the list of network ports exposed by each endpoint in this slice. Each port must have a unique name. Each slice may include a maximum of 100 ports. Services always have at least 1 port, so EndpointSlices generated by the EndpointSlice controller will likewise always have at least 1 port. EndpointSlices used for other purposes may have an empty ports list.", } func (EndpointSlice) SwaggerDoc() map[string]string { @@ -97,6 +98,15 @@ func (EndpointSliceList) SwaggerDoc() map[string]string { return map_EndpointSliceList } +var map_ForNode = map[string]string{ + "": "ForNode provides information about which nodes should consume this endpoint.", + "name": "name represents the name of the node.", +} + +func (ForNode) SwaggerDoc() map[string]string { + return map_ForNode +} + var map_ForZone = map[string]string{ "": "ForZone provides information about which zones should consume this endpoint.", "name": "name represents the name of the zone.", diff --git a/go-controller/vendor/k8s.io/api/discovery/v1/zz_generated.deepcopy.go b/go-controller/vendor/k8s.io/api/discovery/v1/zz_generated.deepcopy.go index caa872af00..60eada3b9f 100644 --- a/go-controller/vendor/k8s.io/api/discovery/v1/zz_generated.deepcopy.go +++ b/go-controller/vendor/k8s.io/api/discovery/v1/zz_generated.deepcopy.go @@ -119,6 +119,11 @@ func (in *EndpointHints) DeepCopyInto(out *EndpointHints) { *out = make([]ForZone, len(*in)) copy(*out, *in) } + if in.ForNodes != nil { + in, out := &in.ForNodes, &out.ForNodes + *out = make([]ForNode, len(*in)) + copy(*out, *in) + } return } @@ -241,6 +246,22 @@ func (in *EndpointSliceList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ForNode) DeepCopyInto(out *ForNode) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ForNode. +func (in *ForNode) DeepCopy() *ForNode { + if in == nil { + return nil + } + out := new(ForNode) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ForZone) DeepCopyInto(out *ForZone) { *out = *in diff --git a/go-controller/vendor/k8s.io/api/discovery/v1beta1/doc.go b/go-controller/vendor/k8s.io/api/discovery/v1beta1/doc.go index 7d7084802d..f12087eff1 100644 --- a/go-controller/vendor/k8s.io/api/discovery/v1beta1/doc.go +++ b/go-controller/vendor/k8s.io/api/discovery/v1beta1/doc.go @@ -20,4 +20,4 @@ limitations under the License. // +k8s:prerelease-lifecycle-gen=true // +groupName=discovery.k8s.io -package v1beta1 // import "k8s.io/api/discovery/v1beta1" +package v1beta1 diff --git a/go-controller/vendor/k8s.io/api/discovery/v1beta1/generated.pb.go b/go-controller/vendor/k8s.io/api/discovery/v1beta1/generated.pb.go index 46935574bf..de32577864 100644 --- a/go-controller/vendor/k8s.io/api/discovery/v1beta1/generated.pb.go +++ b/go-controller/vendor/k8s.io/api/discovery/v1beta1/generated.pb.go @@ -214,10 +214,38 @@ func (m *EndpointSliceList) XXX_DiscardUnknown() { var xxx_messageInfo_EndpointSliceList proto.InternalMessageInfo +func (m *ForNode) Reset() { *m = ForNode{} } +func (*ForNode) ProtoMessage() {} +func (*ForNode) Descriptor() ([]byte, []int) { + return fileDescriptor_6555bad15de200e0, []int{6} +} +func (m *ForNode) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ForNode) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ForNode) XXX_Merge(src proto.Message) { + xxx_messageInfo_ForNode.Merge(m, src) +} +func (m *ForNode) XXX_Size() int { + return m.Size() +} +func (m *ForNode) XXX_DiscardUnknown() { + xxx_messageInfo_ForNode.DiscardUnknown(m) +} + +var xxx_messageInfo_ForNode proto.InternalMessageInfo + func (m *ForZone) Reset() { *m = ForZone{} } func (*ForZone) ProtoMessage() {} func (*ForZone) Descriptor() ([]byte, []int) { - return fileDescriptor_6555bad15de200e0, []int{6} + return fileDescriptor_6555bad15de200e0, []int{7} } func (m *ForZone) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -250,6 +278,7 @@ func init() { proto.RegisterType((*EndpointPort)(nil), "k8s.io.api.discovery.v1beta1.EndpointPort") proto.RegisterType((*EndpointSlice)(nil), "k8s.io.api.discovery.v1beta1.EndpointSlice") proto.RegisterType((*EndpointSliceList)(nil), "k8s.io.api.discovery.v1beta1.EndpointSliceList") + proto.RegisterType((*ForNode)(nil), "k8s.io.api.discovery.v1beta1.ForNode") proto.RegisterType((*ForZone)(nil), "k8s.io.api.discovery.v1beta1.ForZone") } @@ -258,61 +287,62 @@ func init() { } var fileDescriptor_6555bad15de200e0 = []byte{ - // 857 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x55, 0x4f, 0x6f, 0xe4, 0x34, - 0x14, 0x9f, 0x74, 0x1a, 0x9a, 0x78, 0x5a, 0xb1, 0x6b, 0x71, 0x18, 0x95, 0x2a, 0x19, 0x05, 0x2d, + // 877 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x56, 0x4f, 0x6f, 0xe4, 0x34, + 0x1c, 0x9d, 0x74, 0x1a, 0x9a, 0x78, 0x5a, 0xb1, 0x6b, 0x71, 0x18, 0x95, 0x2a, 0x19, 0x05, 0x2d, 0x1a, 0x51, 0x48, 0x68, 0xb5, 0x42, 0x2b, 0x38, 0x35, 0xb0, 0xb0, 0x48, 0xcb, 0x6e, 0xe5, 0x56, 0x42, 0x5a, 0x71, 0xc0, 0x93, 0xb8, 0x19, 0xd3, 0x26, 0x8e, 0x62, 0x77, 0xa4, 0xb9, 0xf1, 0x0d, - 0xe0, 0xb3, 0xf0, 0x15, 0x90, 0x50, 0x8f, 0x7b, 0xdc, 0x53, 0xc4, 0x84, 0x6f, 0xb1, 0x27, 0x64, - 0xc7, 0xf9, 0x33, 0x0c, 0x94, 0xb9, 0xc5, 0x3f, 0xbf, 0xdf, 0xef, 0xbd, 0xf7, 0x7b, 0xb6, 0x03, - 0x3e, 0xbe, 0x7e, 0xc2, 0x7d, 0xca, 0x02, 0x9c, 0xd3, 0x20, 0xa6, 0x3c, 0x62, 0x0b, 0x52, 0x2c, - 0x83, 0xc5, 0xc9, 0x8c, 0x08, 0x7c, 0x12, 0x24, 0x24, 0x23, 0x05, 0x16, 0x24, 0xf6, 0xf3, 0x82, - 0x09, 0x06, 0x8f, 0xea, 0x68, 0x1f, 0xe7, 0xd4, 0x6f, 0xa3, 0x7d, 0x1d, 0x7d, 0xf8, 0x49, 0x42, - 0xc5, 0xfc, 0x76, 0xe6, 0x47, 0x2c, 0x0d, 0x12, 0x96, 0xb0, 0x40, 0x91, 0x66, 0xb7, 0x57, 0x6a, - 0xa5, 0x16, 0xea, 0xab, 0x16, 0x3b, 0xf4, 0x7a, 0xa9, 0x23, 0x56, 0x90, 0x60, 0xb1, 0x91, 0xf0, - 0xf0, 0x71, 0x17, 0x93, 0xe2, 0x68, 0x4e, 0x33, 0x59, 0x5d, 0x7e, 0x9d, 0x48, 0x80, 0x07, 0x29, - 0x11, 0xf8, 0xdf, 0x58, 0xc1, 0x7f, 0xb1, 0x8a, 0xdb, 0x4c, 0xd0, 0x94, 0x6c, 0x10, 0x3e, 0xfb, - 0x3f, 0x02, 0x8f, 0xe6, 0x24, 0xc5, 0xff, 0xe4, 0x79, 0xbf, 0xed, 0x02, 0xeb, 0x69, 0x16, 0xe7, - 0x8c, 0x66, 0x02, 0x1e, 0x03, 0x1b, 0xc7, 0x71, 0x41, 0x38, 0x27, 0x7c, 0x6c, 0x4c, 0x86, 0x53, - 0x3b, 0x3c, 0xa8, 0x4a, 0xd7, 0x3e, 0x6b, 0x40, 0xd4, 0xed, 0xc3, 0x18, 0x80, 0x88, 0x65, 0x31, - 0x15, 0x94, 0x65, 0x7c, 0xbc, 0x33, 0x31, 0xa6, 0xa3, 0xd3, 0x4f, 0xfd, 0xfb, 0xec, 0xf5, 0x9b, - 0x44, 0x5f, 0xb6, 0xbc, 0x10, 0xde, 0x95, 0xee, 0xa0, 0x2a, 0x5d, 0xd0, 0x61, 0xa8, 0xa7, 0x0b, - 0xa7, 0xc0, 0x9a, 0x33, 0x2e, 0x32, 0x9c, 0x92, 0xf1, 0x70, 0x62, 0x4c, 0xed, 0x70, 0xbf, 0x2a, - 0x5d, 0xeb, 0x99, 0xc6, 0x50, 0xbb, 0x0b, 0xcf, 0x81, 0x2d, 0x70, 0x91, 0x10, 0x81, 0xc8, 0xd5, - 0x78, 0x57, 0x95, 0xf3, 0x41, 0xbf, 0x1c, 0x39, 0x20, 0x7f, 0x71, 0xe2, 0xbf, 0x9c, 0xfd, 0x44, - 0x22, 0x19, 0x44, 0x0a, 0x92, 0x45, 0xa4, 0xee, 0xf0, 0xb2, 0x61, 0xa2, 0x4e, 0x04, 0xce, 0x80, - 0x25, 0x58, 0xce, 0x6e, 0x58, 0xb2, 0x1c, 0x9b, 0x93, 0xe1, 0x74, 0x74, 0xfa, 0x78, 0xbb, 0xfe, - 0xfc, 0x4b, 0x4d, 0x7b, 0x9a, 0x89, 0x62, 0x19, 0x3e, 0xd0, 0x3d, 0x5a, 0x0d, 0x8c, 0x5a, 0x5d, - 0xd9, 0x5f, 0xc6, 0x62, 0xf2, 0x42, 0xf6, 0xf7, 0x4e, 0xd7, 0xdf, 0x0b, 0x8d, 0xa1, 0x76, 0x17, - 0x3e, 0x07, 0xe6, 0x9c, 0x66, 0x82, 0x8f, 0xf7, 0x54, 0x6f, 0xc7, 0xdb, 0x95, 0xf2, 0x4c, 0x52, - 0x42, 0xbb, 0x2a, 0x5d, 0x53, 0x7d, 0xa2, 0x5a, 0xe4, 0xf0, 0x0b, 0x70, 0xb0, 0x56, 0x24, 0x7c, - 0x00, 0x86, 0xd7, 0x64, 0x39, 0x36, 0x64, 0x0d, 0x48, 0x7e, 0xc2, 0xf7, 0x80, 0xb9, 0xc0, 0x37, - 0xb7, 0x44, 0xcd, 0xd6, 0x46, 0xf5, 0xe2, 0xf3, 0x9d, 0x27, 0x86, 0xf7, 0x8b, 0x01, 0xe0, 0xe6, - 0x2c, 0xa1, 0x0b, 0xcc, 0x82, 0xe0, 0xb8, 0x16, 0xb1, 0xea, 0xa4, 0x48, 0x02, 0xa8, 0xc6, 0xe1, - 0x23, 0xb0, 0xc7, 0x49, 0xb1, 0xa0, 0x59, 0xa2, 0x34, 0xad, 0x70, 0x54, 0x95, 0xee, 0xde, 0x45, - 0x0d, 0xa1, 0x66, 0x0f, 0x9e, 0x80, 0x91, 0x20, 0x45, 0x4a, 0x33, 0x2c, 0x64, 0xe8, 0x50, 0x85, - 0xbe, 0x5b, 0x95, 0xee, 0xe8, 0xb2, 0x83, 0x51, 0x3f, 0xc6, 0x8b, 0xc1, 0xc1, 0x5a, 0xc7, 0xf0, - 0x02, 0x58, 0x57, 0xac, 0x78, 0xc5, 0x32, 0x7d, 0x92, 0x47, 0xa7, 0x8f, 0xee, 0x37, 0xec, 0xeb, - 0x3a, 0xba, 0x1b, 0x96, 0x06, 0x38, 0x6a, 0x85, 0xbc, 0x3f, 0x0c, 0xb0, 0xdf, 0xa4, 0x39, 0x67, - 0x85, 0x80, 0x47, 0x60, 0x57, 0x9d, 0x4c, 0xe5, 0x5a, 0x68, 0x55, 0xa5, 0xbb, 0xab, 0xa6, 0xa6, - 0x50, 0xf8, 0x0d, 0xb0, 0xd4, 0x25, 0x8b, 0xd8, 0x4d, 0xed, 0x61, 0x78, 0x2c, 0x85, 0xcf, 0x35, - 0xf6, 0xb6, 0x74, 0xdf, 0xdf, 0x7c, 0x40, 0xfc, 0x66, 0x1b, 0xb5, 0x64, 0x99, 0x26, 0x67, 0x85, - 0x50, 0x4e, 0x98, 0x75, 0x1a, 0x99, 0x1e, 0x29, 0x54, 0xda, 0x85, 0xf3, 0xbc, 0xa1, 0xa9, 0xa3, - 0x6f, 0xd7, 0x76, 0x9d, 0x75, 0x30, 0xea, 0xc7, 0x78, 0xab, 0x9d, 0xce, 0xaf, 0x8b, 0x1b, 0x1a, - 0x11, 0xf8, 0x23, 0xb0, 0xe4, 0x5b, 0x14, 0x63, 0x81, 0x55, 0x37, 0xeb, 0x77, 0xb9, 0x7d, 0x52, - 0xfc, 0xfc, 0x3a, 0x91, 0x00, 0xf7, 0x65, 0x74, 0x77, 0x9d, 0xbe, 0x23, 0x02, 0x77, 0x77, 0xb9, - 0xc3, 0x50, 0xab, 0x0a, 0xbf, 0x02, 0x23, 0xfd, 0x78, 0x5c, 0x2e, 0x73, 0xa2, 0xcb, 0xf4, 0x34, - 0x65, 0x74, 0xd6, 0x6d, 0xbd, 0x5d, 0x5f, 0xa2, 0x3e, 0x0d, 0x7e, 0x0f, 0x6c, 0xa2, 0x0b, 0x97, - 0x8f, 0x8e, 0x1c, 0xec, 0x87, 0xdb, 0xdd, 0x84, 0xf0, 0xa1, 0xce, 0x65, 0x37, 0x08, 0x47, 0x9d, - 0x16, 0x7c, 0x09, 0x4c, 0xe9, 0x26, 0x1f, 0x0f, 0x95, 0xe8, 0x47, 0xdb, 0x89, 0xca, 0x31, 0x84, - 0x07, 0x5a, 0xd8, 0x94, 0x2b, 0x8e, 0x6a, 0x1d, 0xef, 0x77, 0x03, 0x3c, 0x5c, 0xf3, 0xf8, 0x39, - 0xe5, 0x02, 0xfe, 0xb0, 0xe1, 0xb3, 0xbf, 0x9d, 0xcf, 0x92, 0xad, 0x5c, 0x6e, 0x0f, 0x68, 0x83, - 0xf4, 0x3c, 0x3e, 0x07, 0x26, 0x15, 0x24, 0x6d, 0x9c, 0xd9, 0xf2, 0x8d, 0x50, 0xd5, 0x75, 0x5d, - 0x7c, 0x2b, 0x15, 0x50, 0x2d, 0xe4, 0x1d, 0x83, 0x3d, 0x7d, 0x11, 0xe0, 0x64, 0xed, 0xb0, 0xef, - 0xeb, 0xf0, 0xde, 0x81, 0x0f, 0xc3, 0xbb, 0x95, 0x33, 0x78, 0xbd, 0x72, 0x06, 0x6f, 0x56, 0xce, - 0xe0, 0xe7, 0xca, 0x31, 0xee, 0x2a, 0xc7, 0x78, 0x5d, 0x39, 0xc6, 0x9b, 0xca, 0x31, 0xfe, 0xac, - 0x1c, 0xe3, 0xd7, 0xbf, 0x9c, 0xc1, 0xab, 0xa3, 0xfb, 0x7e, 0xd8, 0x7f, 0x07, 0x00, 0x00, 0xff, - 0xff, 0x1c, 0xe6, 0x20, 0x06, 0xcf, 0x07, 0x00, 0x00, + 0xe0, 0xb3, 0x70, 0xe3, 0x8c, 0x84, 0x7a, 0xdc, 0xe3, 0x9e, 0x22, 0x1a, 0xbe, 0xc5, 0x9e, 0x90, + 0x1d, 0xe7, 0xcf, 0x30, 0xd0, 0xce, 0x2d, 0x7e, 0x7e, 0xef, 0xfd, 0xfe, 0xd9, 0x56, 0xc0, 0xc7, + 0x97, 0x4f, 0xb8, 0x4f, 0x59, 0x80, 0x73, 0x1a, 0xc4, 0x94, 0x47, 0x6c, 0x41, 0x8a, 0x65, 0xb0, + 0x38, 0x9a, 0x11, 0x81, 0x8f, 0x82, 0x84, 0x64, 0xa4, 0xc0, 0x82, 0xc4, 0x7e, 0x5e, 0x30, 0xc1, + 0xe0, 0x41, 0xcd, 0xf6, 0x71, 0x4e, 0xfd, 0x96, 0xed, 0x6b, 0xf6, 0xfe, 0x27, 0x09, 0x15, 0xf3, + 0xeb, 0x99, 0x1f, 0xb1, 0x34, 0x48, 0x58, 0xc2, 0x02, 0x25, 0x9a, 0x5d, 0x5f, 0xa8, 0x95, 0x5a, + 0xa8, 0xaf, 0xda, 0x6c, 0xdf, 0xeb, 0x85, 0x8e, 0x58, 0x41, 0x82, 0xc5, 0x5a, 0xc0, 0xfd, 0xc7, + 0x1d, 0x27, 0xc5, 0xd1, 0x9c, 0x66, 0x32, 0xbb, 0xfc, 0x32, 0x91, 0x00, 0x0f, 0x52, 0x22, 0xf0, + 0x7f, 0xa9, 0x82, 0xff, 0x53, 0x15, 0xd7, 0x99, 0xa0, 0x29, 0x59, 0x13, 0x7c, 0x76, 0x9f, 0x80, + 0x47, 0x73, 0x92, 0xe2, 0x7f, 0xeb, 0xbc, 0xdf, 0xb6, 0x81, 0xf5, 0x34, 0x8b, 0x73, 0x46, 0x33, + 0x01, 0x0f, 0x81, 0x8d, 0xe3, 0xb8, 0x20, 0x9c, 0x13, 0x3e, 0x36, 0x26, 0xc3, 0xa9, 0x1d, 0xee, + 0x55, 0xa5, 0x6b, 0x9f, 0x34, 0x20, 0xea, 0xf6, 0x61, 0x0c, 0x40, 0xc4, 0xb2, 0x98, 0x0a, 0xca, + 0x32, 0x3e, 0xde, 0x9a, 0x18, 0xd3, 0xd1, 0xf1, 0xa7, 0xfe, 0x5d, 0xed, 0xf5, 0x9b, 0x40, 0x5f, + 0xb6, 0xba, 0x10, 0xde, 0x94, 0xee, 0xa0, 0x2a, 0x5d, 0xd0, 0x61, 0xa8, 0xe7, 0x0b, 0xa7, 0xc0, + 0x9a, 0x33, 0x2e, 0x32, 0x9c, 0x92, 0xf1, 0x70, 0x62, 0x4c, 0xed, 0x70, 0xb7, 0x2a, 0x5d, 0xeb, + 0x99, 0xc6, 0x50, 0xbb, 0x0b, 0x4f, 0x81, 0x2d, 0x70, 0x91, 0x10, 0x81, 0xc8, 0xc5, 0x78, 0x5b, + 0xa5, 0xf3, 0x41, 0x3f, 0x1d, 0x39, 0x20, 0x7f, 0x71, 0xe4, 0xbf, 0x9c, 0xfd, 0x44, 0x22, 0x49, + 0x22, 0x05, 0xc9, 0x22, 0x52, 0x57, 0x78, 0xde, 0x28, 0x51, 0x67, 0x02, 0x67, 0xc0, 0x12, 0x2c, + 0x67, 0x57, 0x2c, 0x59, 0x8e, 0xcd, 0xc9, 0x70, 0x3a, 0x3a, 0x7e, 0xbc, 0x59, 0x7d, 0xfe, 0xb9, + 0x96, 0x3d, 0xcd, 0x44, 0xb1, 0x0c, 0x1f, 0xe8, 0x1a, 0xad, 0x06, 0x46, 0xad, 0xaf, 0xac, 0x2f, + 0x63, 0x31, 0x79, 0x21, 0xeb, 0x7b, 0xa7, 0xab, 0xef, 0x85, 0xc6, 0x50, 0xbb, 0x0b, 0x9f, 0x03, + 0x73, 0x4e, 0x33, 0xc1, 0xc7, 0x3b, 0xaa, 0xb6, 0xc3, 0xcd, 0x52, 0x79, 0x26, 0x25, 0xa1, 0x5d, + 0x95, 0xae, 0xa9, 0x3e, 0x51, 0x6d, 0xb2, 0xff, 0x05, 0xd8, 0x5b, 0x49, 0x12, 0x3e, 0x00, 0xc3, + 0x4b, 0xb2, 0x1c, 0x1b, 0x32, 0x07, 0x24, 0x3f, 0xe1, 0x7b, 0xc0, 0x5c, 0xe0, 0xab, 0x6b, 0xa2, + 0x66, 0x6b, 0xa3, 0x7a, 0xf1, 0xf9, 0xd6, 0x13, 0xc3, 0xfb, 0xc5, 0x00, 0x70, 0x7d, 0x96, 0xd0, + 0x05, 0x66, 0x41, 0x70, 0x5c, 0x9b, 0x58, 0x75, 0x50, 0x24, 0x01, 0x54, 0xe3, 0xf0, 0x11, 0xd8, + 0xe1, 0xa4, 0x58, 0xd0, 0x2c, 0x51, 0x9e, 0x56, 0x38, 0xaa, 0x4a, 0x77, 0xe7, 0xac, 0x86, 0x50, + 0xb3, 0x07, 0x8f, 0xc0, 0x48, 0x90, 0x22, 0xa5, 0x19, 0x16, 0x92, 0x3a, 0x54, 0xd4, 0x77, 0xab, + 0xd2, 0x1d, 0x9d, 0x77, 0x30, 0xea, 0x73, 0xbc, 0xdf, 0x0d, 0xb0, 0xb7, 0x52, 0x32, 0x3c, 0x03, + 0xd6, 0x05, 0x2b, 0x5e, 0xb1, 0x4c, 0x1f, 0xe5, 0xd1, 0xf1, 0xa3, 0xbb, 0x3b, 0xf6, 0x75, 0xcd, + 0xee, 0xa6, 0xa5, 0x01, 0x8e, 0x5a, 0x23, 0x6d, 0x2a, 0x87, 0x23, 0x4f, 0xfc, 0x66, 0xa6, 0x92, + 0xbd, 0x62, 0xaa, 0xe4, 0xa8, 0x35, 0xf2, 0xfe, 0x34, 0xc0, 0x6e, 0x93, 0xfb, 0x29, 0x2b, 0x04, + 0x3c, 0x00, 0xdb, 0xea, 0xbc, 0xab, 0x59, 0x84, 0x56, 0x55, 0xba, 0xdb, 0xea, 0x2c, 0x28, 0x14, + 0x7e, 0x03, 0x2c, 0x75, 0x75, 0x23, 0x76, 0x55, 0x4f, 0x26, 0x3c, 0x94, 0xc6, 0xa7, 0x1a, 0x7b, + 0x5b, 0xba, 0xef, 0xaf, 0x3f, 0x4b, 0x7e, 0xb3, 0x8d, 0x5a, 0xb1, 0x0c, 0x93, 0xb3, 0x42, 0xa8, + 0xfe, 0x9a, 0x75, 0x18, 0x19, 0x1e, 0x29, 0x54, 0x0e, 0x01, 0xe7, 0x79, 0x23, 0x53, 0x17, 0xca, + 0xae, 0x87, 0x70, 0xd2, 0xc1, 0xa8, 0xcf, 0xf1, 0x6e, 0xb7, 0xba, 0x21, 0x9c, 0x5d, 0xd1, 0x88, + 0xc0, 0x1f, 0x81, 0x25, 0x5f, 0xb8, 0x18, 0x0b, 0xac, 0xaa, 0x59, 0x7d, 0x21, 0xda, 0x87, 0xca, + 0xcf, 0x2f, 0x13, 0x09, 0x70, 0x5f, 0xb2, 0xbb, 0x4b, 0xfa, 0x1d, 0x11, 0xb8, 0x7b, 0x21, 0x3a, + 0x0c, 0xb5, 0xae, 0xf0, 0x2b, 0x30, 0xd2, 0x4f, 0xd2, 0xf9, 0x32, 0x27, 0x3a, 0x4d, 0x4f, 0x4b, + 0x46, 0x27, 0xdd, 0xd6, 0xdb, 0xd5, 0x25, 0xea, 0xcb, 0xe0, 0xf7, 0xc0, 0x26, 0x3a, 0xf1, 0x66, + 0xb0, 0x1f, 0x6e, 0x76, 0xbf, 0xc2, 0x87, 0x3a, 0x96, 0xdd, 0x20, 0x1c, 0x75, 0x5e, 0xf0, 0x25, + 0x30, 0x65, 0x37, 0xf9, 0x78, 0xa8, 0x4c, 0x3f, 0xda, 0xcc, 0x54, 0x8e, 0x21, 0xdc, 0xd3, 0xc6, + 0xa6, 0x5c, 0x71, 0x54, 0xfb, 0x78, 0x7f, 0x18, 0xe0, 0xe1, 0x4a, 0x8f, 0x9f, 0x53, 0x2e, 0xe0, + 0x0f, 0x6b, 0x7d, 0xf6, 0x37, 0xeb, 0xb3, 0x54, 0xab, 0x2e, 0xb7, 0x07, 0xb4, 0x41, 0x7a, 0x3d, + 0x3e, 0x05, 0x26, 0x15, 0x24, 0x6d, 0x3a, 0xb3, 0xe1, 0xcb, 0xa3, 0xb2, 0xeb, 0xaa, 0xf8, 0x56, + 0x3a, 0xa0, 0xda, 0xc8, 0x3b, 0x04, 0x3b, 0xfa, 0x22, 0xc0, 0xc9, 0xca, 0x61, 0xdf, 0xd5, 0xf4, + 0xde, 0x81, 0xd7, 0x64, 0x79, 0x01, 0xef, 0x27, 0x87, 0xe1, 0xcd, 0xad, 0x33, 0x78, 0x7d, 0xeb, + 0x0c, 0xde, 0xdc, 0x3a, 0x83, 0x9f, 0x2b, 0xc7, 0xb8, 0xa9, 0x1c, 0xe3, 0x75, 0xe5, 0x18, 0x6f, + 0x2a, 0xc7, 0xf8, 0xab, 0x72, 0x8c, 0x5f, 0xff, 0x76, 0x06, 0xaf, 0x0e, 0xee, 0xfa, 0x67, 0xf8, + 0x27, 0x00, 0x00, 0xff, 0xff, 0x76, 0x8e, 0x48, 0x7e, 0x52, 0x08, 0x00, 0x00, } func (m *Endpoint) Marshal() (dAtA []byte, err error) { @@ -492,6 +522,20 @@ func (m *EndpointHints) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.ForNodes) > 0 { + for iNdEx := len(m.ForNodes) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ForNodes[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } if len(m.ForZones) > 0 { for iNdEx := len(m.ForZones) - 1; iNdEx >= 0; iNdEx-- { { @@ -671,6 +715,34 @@ func (m *EndpointSliceList) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *ForNode) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ForNode) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ForNode) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *ForZone) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -781,6 +853,12 @@ func (m *EndpointHints) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) } } + if len(m.ForNodes) > 0 { + for _, e := range m.ForNodes { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } return n } @@ -850,6 +928,17 @@ func (m *EndpointSliceList) Size() (n int) { return n } +func (m *ForNode) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + func (m *ForZone) Size() (n int) { if m == nil { return 0 @@ -914,8 +1003,14 @@ func (this *EndpointHints) String() string { repeatedStringForForZones += strings.Replace(strings.Replace(f.String(), "ForZone", "ForZone", 1), `&`, ``, 1) + "," } repeatedStringForForZones += "}" + repeatedStringForForNodes := "[]ForNode{" + for _, f := range this.ForNodes { + repeatedStringForForNodes += strings.Replace(strings.Replace(f.String(), "ForNode", "ForNode", 1), `&`, ``, 1) + "," + } + repeatedStringForForNodes += "}" s := strings.Join([]string{`&EndpointHints{`, `ForZones:` + repeatedStringForForZones + `,`, + `ForNodes:` + repeatedStringForForNodes + `,`, `}`, }, "") return s @@ -972,6 +1067,16 @@ func (this *EndpointSliceList) String() string { }, "") return s } +func (this *ForNode) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ForNode{`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `}`, + }, "") + return s +} func (this *ForZone) String() string { if this == nil { return "nil" @@ -1546,6 +1651,40 @@ func (m *EndpointHints) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ForNodes", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ForNodes = append(m.ForNodes, ForNode{}) + if err := m.ForNodes[len(m.ForNodes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -2036,6 +2175,88 @@ func (m *EndpointSliceList) Unmarshal(dAtA []byte) error { } return nil } +func (m *ForNode) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ForNode: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ForNode: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *ForZone) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/go-controller/vendor/k8s.io/api/discovery/v1beta1/generated.proto b/go-controller/vendor/k8s.io/api/discovery/v1beta1/generated.proto index 55828dd97d..907050da1c 100644 --- a/go-controller/vendor/k8s.io/api/discovery/v1beta1/generated.proto +++ b/go-controller/vendor/k8s.io/api/discovery/v1beta1/generated.proto @@ -114,6 +114,13 @@ message EndpointHints { // enable topology aware routing. May contain a maximum of 8 entries. // +listType=atomic repeated ForZone forZones = 1; + + // forNodes indicates the node(s) this endpoint should be consumed by when + // using topology aware routing. May contain a maximum of 8 entries. + // This is an Alpha feature and is only used when the PreferSameTrafficDistribution + // feature gate is enabled. + // +listType=atomic + repeated ForNode forNodes = 2; } // EndpointPort represents a Port used by an EndpointSlice @@ -189,6 +196,12 @@ message EndpointSliceList { repeated EndpointSlice items = 2; } +// ForNode provides information about which nodes should consume this endpoint. +message ForNode { + // name represents the name of the node. + optional string name = 1; +} + // ForZone provides information about which zones should consume this endpoint. message ForZone { // name represents the name of the zone. diff --git a/go-controller/vendor/k8s.io/api/discovery/v1beta1/types.go b/go-controller/vendor/k8s.io/api/discovery/v1beta1/types.go index defd8e2ce6..fa9d1eae43 100644 --- a/go-controller/vendor/k8s.io/api/discovery/v1beta1/types.go +++ b/go-controller/vendor/k8s.io/api/discovery/v1beta1/types.go @@ -161,6 +161,13 @@ type EndpointHints struct { // enable topology aware routing. May contain a maximum of 8 entries. // +listType=atomic ForZones []ForZone `json:"forZones,omitempty" protobuf:"bytes,1,name=forZones"` + + // forNodes indicates the node(s) this endpoint should be consumed by when + // using topology aware routing. May contain a maximum of 8 entries. + // This is an Alpha feature and is only used when the PreferSameTrafficDistribution + // feature gate is enabled. + // +listType=atomic + ForNodes []ForNode `json:"forNodes,omitempty" protobuf:"bytes,2,name=forNodes"` } // ForZone provides information about which zones should consume this endpoint. @@ -169,6 +176,12 @@ type ForZone struct { Name string `json:"name" protobuf:"bytes,1,name=name"` } +// ForNode provides information about which nodes should consume this endpoint. +type ForNode struct { + // name represents the name of the node. + Name string `json:"name" protobuf:"bytes,1,name=name"` +} + // EndpointPort represents a Port used by an EndpointSlice type EndpointPort struct { // name represents the name of this port. All ports in an EndpointSlice must have a unique name. diff --git a/go-controller/vendor/k8s.io/api/discovery/v1beta1/types_swagger_doc_generated.go b/go-controller/vendor/k8s.io/api/discovery/v1beta1/types_swagger_doc_generated.go index 847d4d58e0..72aa0cb9b2 100644 --- a/go-controller/vendor/k8s.io/api/discovery/v1beta1/types_swagger_doc_generated.go +++ b/go-controller/vendor/k8s.io/api/discovery/v1beta1/types_swagger_doc_generated.go @@ -56,6 +56,7 @@ func (EndpointConditions) SwaggerDoc() map[string]string { var map_EndpointHints = map[string]string{ "": "EndpointHints provides hints describing how an endpoint should be consumed.", "forZones": "forZones indicates the zone(s) this endpoint should be consumed by to enable topology aware routing. May contain a maximum of 8 entries.", + "forNodes": "forNodes indicates the node(s) this endpoint should be consumed by when using topology aware routing. May contain a maximum of 8 entries. This is an Alpha feature and is only used when the PreferSameTrafficDistribution feature gate is enabled.", } func (EndpointHints) SwaggerDoc() map[string]string { @@ -96,6 +97,15 @@ func (EndpointSliceList) SwaggerDoc() map[string]string { return map_EndpointSliceList } +var map_ForNode = map[string]string{ + "": "ForNode provides information about which nodes should consume this endpoint.", + "name": "name represents the name of the node.", +} + +func (ForNode) SwaggerDoc() map[string]string { + return map_ForNode +} + var map_ForZone = map[string]string{ "": "ForZone provides information about which zones should consume this endpoint.", "name": "name represents the name of the zone.", diff --git a/go-controller/vendor/k8s.io/api/discovery/v1beta1/zz_generated.deepcopy.go b/go-controller/vendor/k8s.io/api/discovery/v1beta1/zz_generated.deepcopy.go index 13b9544b0c..72490d6adf 100644 --- a/go-controller/vendor/k8s.io/api/discovery/v1beta1/zz_generated.deepcopy.go +++ b/go-controller/vendor/k8s.io/api/discovery/v1beta1/zz_generated.deepcopy.go @@ -114,6 +114,11 @@ func (in *EndpointHints) DeepCopyInto(out *EndpointHints) { *out = make([]ForZone, len(*in)) copy(*out, *in) } + if in.ForNodes != nil { + in, out := &in.ForNodes, &out.ForNodes + *out = make([]ForNode, len(*in)) + copy(*out, *in) + } return } @@ -236,6 +241,22 @@ func (in *EndpointSliceList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ForNode) DeepCopyInto(out *ForNode) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ForNode. +func (in *ForNode) DeepCopy() *ForNode { + if in == nil { + return nil + } + out := new(ForNode) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ForZone) DeepCopyInto(out *ForZone) { *out = *in diff --git a/go-controller/vendor/k8s.io/api/events/v1/doc.go b/go-controller/vendor/k8s.io/api/events/v1/doc.go index 5fe700ffcf..911639044f 100644 --- a/go-controller/vendor/k8s.io/api/events/v1/doc.go +++ b/go-controller/vendor/k8s.io/api/events/v1/doc.go @@ -20,4 +20,4 @@ limitations under the License. // +k8s:prerelease-lifecycle-gen=true // +groupName=events.k8s.io -package v1 // import "k8s.io/api/events/v1" +package v1 diff --git a/go-controller/vendor/k8s.io/api/events/v1beta1/doc.go b/go-controller/vendor/k8s.io/api/events/v1beta1/doc.go index 46048a65b4..e4864294fd 100644 --- a/go-controller/vendor/k8s.io/api/events/v1beta1/doc.go +++ b/go-controller/vendor/k8s.io/api/events/v1beta1/doc.go @@ -21,4 +21,4 @@ limitations under the License. // +groupName=events.k8s.io -package v1beta1 // import "k8s.io/api/events/v1beta1" +package v1beta1 diff --git a/go-controller/vendor/k8s.io/api/extensions/v1beta1/doc.go b/go-controller/vendor/k8s.io/api/extensions/v1beta1/doc.go index c9af49d55c..7770fab5d2 100644 --- a/go-controller/vendor/k8s.io/api/extensions/v1beta1/doc.go +++ b/go-controller/vendor/k8s.io/api/extensions/v1beta1/doc.go @@ -19,4 +19,4 @@ limitations under the License. // +k8s:openapi-gen=true // +k8s:prerelease-lifecycle-gen=true -package v1beta1 // import "k8s.io/api/extensions/v1beta1" +package v1beta1 diff --git a/go-controller/vendor/k8s.io/api/extensions/v1beta1/generated.pb.go b/go-controller/vendor/k8s.io/api/extensions/v1beta1/generated.pb.go index 818486f39d..35b9a4ff2a 100644 --- a/go-controller/vendor/k8s.io/api/extensions/v1beta1/generated.pb.go +++ b/go-controller/vendor/k8s.io/api/extensions/v1beta1/generated.pb.go @@ -1364,185 +1364,187 @@ func init() { } var fileDescriptor_90a532284de28347 = []byte{ - // 2842 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5b, 0xcd, 0x6f, 0x24, 0x47, - 0x15, 0xdf, 0x9e, 0xf1, 0xd8, 0xe3, 0xe7, 0xb5, 0xbd, 0x5b, 0xeb, 0xac, 0x1d, 0x2f, 0xb1, 0xa3, - 0x46, 0x84, 0x4d, 0xd8, 0x9d, 0x61, 0x37, 0xc9, 0x92, 0x0f, 0x29, 0x61, 0xc7, 0xbb, 0xc9, 0x3a, - 0xb1, 0xc7, 0x93, 0x9a, 0x71, 0x82, 0x22, 0x02, 0xb4, 0x7b, 0xca, 0xe3, 0x8e, 0x7b, 0xba, 0x47, - 0xdd, 0x35, 0x66, 0x7d, 0x03, 0xc1, 0x25, 0x27, 0xb8, 0x04, 0x38, 0x22, 0x21, 0x71, 0xe5, 0xca, - 0x21, 0x44, 0x20, 0x82, 0xb4, 0x42, 0x1c, 0x22, 0x71, 0x20, 0x27, 0x8b, 0x38, 0x27, 0xc4, 0x3f, - 0x80, 0xf6, 0x84, 0xea, 0xa3, 0xab, 0xbf, 0xed, 0x1e, 0xe3, 0x58, 0x04, 0x71, 0x5a, 0x4f, 0xbd, - 0xf7, 0x7e, 0xf5, 0xaa, 0xea, 0xd5, 0x7b, 0xbf, 0xaa, 0xea, 0x85, 0xeb, 0xbb, 0xcf, 0xf9, 0x35, - 0xcb, 0xad, 0x1b, 0x03, 0xab, 0x4e, 0xee, 0x53, 0xe2, 0xf8, 0x96, 0xeb, 0xf8, 0xf5, 0xbd, 0x1b, - 0x5b, 0x84, 0x1a, 0x37, 0xea, 0x3d, 0xe2, 0x10, 0xcf, 0xa0, 0xa4, 0x5b, 0x1b, 0x78, 0x2e, 0x75, - 0xd1, 0x63, 0x42, 0xbd, 0x66, 0x0c, 0xac, 0x5a, 0xa8, 0x5e, 0x93, 0xea, 0x8b, 0xd7, 0x7b, 0x16, - 0xdd, 0x19, 0x6e, 0xd5, 0x4c, 0xb7, 0x5f, 0xef, 0xb9, 0x3d, 0xb7, 0xce, 0xad, 0xb6, 0x86, 0xdb, - 0xfc, 0x17, 0xff, 0xc1, 0xff, 0x12, 0x68, 0x8b, 0x7a, 0xa4, 0x73, 0xd3, 0xf5, 0x48, 0x7d, 0x2f, - 0xd5, 0xe3, 0xe2, 0x33, 0xa1, 0x4e, 0xdf, 0x30, 0x77, 0x2c, 0x87, 0x78, 0xfb, 0xf5, 0xc1, 0x6e, - 0x8f, 0x35, 0xf8, 0xf5, 0x3e, 0xa1, 0x46, 0x96, 0x55, 0x3d, 0xcf, 0xca, 0x1b, 0x3a, 0xd4, 0xea, - 0x93, 0x94, 0xc1, 0xad, 0xe3, 0x0c, 0x7c, 0x73, 0x87, 0xf4, 0x8d, 0x94, 0xdd, 0xd3, 0x79, 0x76, - 0x43, 0x6a, 0xd9, 0x75, 0xcb, 0xa1, 0x3e, 0xf5, 0x92, 0x46, 0xfa, 0xfb, 0x25, 0x98, 0xbc, 0x63, - 0x90, 0xbe, 0xeb, 0xb4, 0x09, 0x45, 0xdf, 0x83, 0x2a, 0x1b, 0x46, 0xd7, 0xa0, 0xc6, 0x82, 0xf6, - 0xb8, 0x76, 0x75, 0xea, 0xe6, 0xd7, 0x6b, 0xe1, 0x34, 0x2b, 0xd4, 0xda, 0x60, 0xb7, 0xc7, 0x1a, - 0xfc, 0x1a, 0xd3, 0xae, 0xed, 0xdd, 0xa8, 0x6d, 0x6c, 0xbd, 0x4b, 0x4c, 0xba, 0x4e, 0xa8, 0xd1, - 0x40, 0x0f, 0x0e, 0x96, 0xcf, 0x1d, 0x1e, 0x2c, 0x43, 0xd8, 0x86, 0x15, 0x2a, 0x6a, 0xc2, 0x98, - 0x3f, 0x20, 0xe6, 0x42, 0x89, 0xa3, 0x5f, 0xab, 0x1d, 0xb9, 0x88, 0x35, 0xe5, 0x59, 0x7b, 0x40, - 0xcc, 0xc6, 0x79, 0x89, 0x3c, 0xc6, 0x7e, 0x61, 0x8e, 0x83, 0xde, 0x84, 0x71, 0x9f, 0x1a, 0x74, - 0xe8, 0x2f, 0x94, 0x39, 0x62, 0xad, 0x30, 0x22, 0xb7, 0x6a, 0xcc, 0x48, 0xcc, 0x71, 0xf1, 0x1b, - 0x4b, 0x34, 0xfd, 0x1f, 0x25, 0x40, 0x4a, 0x77, 0xc5, 0x75, 0xba, 0x16, 0xb5, 0x5c, 0x07, 0xbd, - 0x00, 0x63, 0x74, 0x7f, 0x40, 0xf8, 0xe4, 0x4c, 0x36, 0x9e, 0x08, 0x1c, 0xea, 0xec, 0x0f, 0xc8, - 0xc3, 0x83, 0xe5, 0xcb, 0x69, 0x0b, 0x26, 0xc1, 0xdc, 0x06, 0xad, 0x29, 0x57, 0x4b, 0xdc, 0xfa, - 0x99, 0x78, 0xd7, 0x0f, 0x0f, 0x96, 0x33, 0x82, 0xb0, 0xa6, 0x90, 0xe2, 0x0e, 0xa2, 0x3d, 0x40, - 0xb6, 0xe1, 0xd3, 0x8e, 0x67, 0x38, 0xbe, 0xe8, 0xc9, 0xea, 0x13, 0x39, 0x09, 0x4f, 0x15, 0x5b, - 0x34, 0x66, 0xd1, 0x58, 0x94, 0x5e, 0xa0, 0xb5, 0x14, 0x1a, 0xce, 0xe8, 0x01, 0x3d, 0x01, 0xe3, - 0x1e, 0x31, 0x7c, 0xd7, 0x59, 0x18, 0xe3, 0xa3, 0x50, 0x13, 0x88, 0x79, 0x2b, 0x96, 0x52, 0xf4, - 0x24, 0x4c, 0xf4, 0x89, 0xef, 0x1b, 0x3d, 0xb2, 0x50, 0xe1, 0x8a, 0xb3, 0x52, 0x71, 0x62, 0x5d, - 0x34, 0xe3, 0x40, 0xae, 0x7f, 0xa0, 0xc1, 0xb4, 0x9a, 0xb9, 0x35, 0xcb, 0xa7, 0xe8, 0xdb, 0xa9, - 0x38, 0xac, 0x15, 0x1b, 0x12, 0xb3, 0xe6, 0x51, 0x78, 0x41, 0xf6, 0x56, 0x0d, 0x5a, 0x22, 0x31, - 0xb8, 0x0e, 0x15, 0x8b, 0x92, 0x3e, 0x5b, 0x87, 0xf2, 0xd5, 0xa9, 0x9b, 0x57, 0x8b, 0x86, 0x4c, - 0x63, 0x5a, 0x82, 0x56, 0x56, 0x99, 0x39, 0x16, 0x28, 0xfa, 0xcf, 0xc6, 0x22, 0xee, 0xb3, 0xd0, - 0x44, 0xef, 0x40, 0xd5, 0x27, 0x36, 0x31, 0xa9, 0xeb, 0x49, 0xf7, 0x9f, 0x2e, 0xe8, 0xbe, 0xb1, - 0x45, 0xec, 0xb6, 0x34, 0x6d, 0x9c, 0x67, 0xfe, 0x07, 0xbf, 0xb0, 0x82, 0x44, 0x6f, 0x40, 0x95, - 0x92, 0xfe, 0xc0, 0x36, 0x28, 0x91, 0xfb, 0xe8, 0xcb, 0xd1, 0x21, 0xb0, 0xc8, 0x61, 0x60, 0x2d, - 0xb7, 0xdb, 0x91, 0x6a, 0x7c, 0xfb, 0xa8, 0x29, 0x09, 0x5a, 0xb1, 0x82, 0x41, 0x7b, 0x30, 0x33, - 0x1c, 0x74, 0x99, 0x26, 0x65, 0xd9, 0xa1, 0xb7, 0x2f, 0x23, 0xe9, 0x56, 0xd1, 0xb9, 0xd9, 0x8c, - 0x59, 0x37, 0x2e, 0xcb, 0xbe, 0x66, 0xe2, 0xed, 0x38, 0xd1, 0x0b, 0xba, 0x0d, 0xb3, 0x7d, 0xcb, - 0xc1, 0xc4, 0xe8, 0xee, 0xb7, 0x89, 0xe9, 0x3a, 0x5d, 0x9f, 0x87, 0x55, 0xa5, 0x31, 0x2f, 0x01, - 0x66, 0xd7, 0xe3, 0x62, 0x9c, 0xd4, 0x47, 0xaf, 0x01, 0x0a, 0x86, 0xf1, 0xaa, 0x48, 0x6e, 0x96, - 0xeb, 0xf0, 0x98, 0x2b, 0x87, 0xc1, 0xdd, 0x49, 0x69, 0xe0, 0x0c, 0x2b, 0xb4, 0x06, 0x73, 0x1e, - 0xd9, 0xb3, 0xd8, 0x18, 0xef, 0x59, 0x3e, 0x75, 0xbd, 0xfd, 0x35, 0xab, 0x6f, 0xd1, 0x85, 0x71, - 0xee, 0xd3, 0xc2, 0xe1, 0xc1, 0xf2, 0x1c, 0xce, 0x90, 0xe3, 0x4c, 0x2b, 0xfd, 0xe7, 0xe3, 0x30, - 0x9b, 0xc8, 0x37, 0xe8, 0x4d, 0xb8, 0x6c, 0x0e, 0x3d, 0x8f, 0x38, 0xb4, 0x39, 0xec, 0x6f, 0x11, - 0xaf, 0x6d, 0xee, 0x90, 0xee, 0xd0, 0x26, 0x5d, 0x1e, 0x28, 0x95, 0xc6, 0x92, 0xf4, 0xf8, 0xf2, - 0x4a, 0xa6, 0x16, 0xce, 0xb1, 0x66, 0xb3, 0xe0, 0xf0, 0xa6, 0x75, 0xcb, 0xf7, 0x15, 0x66, 0x89, - 0x63, 0xaa, 0x59, 0x68, 0xa6, 0x34, 0x70, 0x86, 0x15, 0xf3, 0xb1, 0x4b, 0x7c, 0xcb, 0x23, 0xdd, - 0xa4, 0x8f, 0xe5, 0xb8, 0x8f, 0x77, 0x32, 0xb5, 0x70, 0x8e, 0x35, 0x7a, 0x16, 0xa6, 0x44, 0x6f, - 0x7c, 0xfd, 0xe4, 0x42, 0x5f, 0x92, 0x60, 0x53, 0xcd, 0x50, 0x84, 0xa3, 0x7a, 0x6c, 0x68, 0xee, - 0x96, 0x4f, 0xbc, 0x3d, 0xd2, 0xcd, 0x5f, 0xe0, 0x8d, 0x94, 0x06, 0xce, 0xb0, 0x62, 0x43, 0x13, - 0x11, 0x98, 0x1a, 0xda, 0x78, 0x7c, 0x68, 0x9b, 0x99, 0x5a, 0x38, 0xc7, 0x9a, 0xc5, 0xb1, 0x70, - 0xf9, 0xf6, 0x9e, 0x61, 0xd9, 0xc6, 0x96, 0x4d, 0x16, 0x26, 0xe2, 0x71, 0xdc, 0x8c, 0x8b, 0x71, - 0x52, 0x1f, 0xbd, 0x0a, 0x17, 0x45, 0xd3, 0xa6, 0x63, 0x28, 0x90, 0x2a, 0x07, 0x79, 0x54, 0x82, - 0x5c, 0x6c, 0x26, 0x15, 0x70, 0xda, 0x06, 0xbd, 0x00, 0x33, 0xa6, 0x6b, 0xdb, 0x3c, 0x1e, 0x57, - 0xdc, 0xa1, 0x43, 0x17, 0x26, 0x39, 0x0a, 0x62, 0xfb, 0x71, 0x25, 0x26, 0xc1, 0x09, 0x4d, 0x44, - 0x00, 0xcc, 0xa0, 0xe0, 0xf8, 0x0b, 0xc0, 0xf3, 0xe3, 0x8d, 0xa2, 0x39, 0x40, 0x95, 0xaa, 0x90, - 0x03, 0xa8, 0x26, 0x1f, 0x47, 0x80, 0xf5, 0x3f, 0x6b, 0x30, 0x9f, 0x93, 0x3a, 0xd0, 0xcb, 0xb1, - 0x12, 0xfb, 0xb5, 0x44, 0x89, 0xbd, 0x92, 0x63, 0x16, 0xa9, 0xb3, 0x0e, 0x4c, 0x7b, 0x6c, 0x54, - 0x4e, 0x4f, 0xa8, 0xc8, 0x1c, 0xf9, 0xec, 0x31, 0xc3, 0xc0, 0x51, 0x9b, 0x30, 0xe7, 0x5f, 0x3c, - 0x3c, 0x58, 0x9e, 0x8e, 0xc9, 0x70, 0x1c, 0x5e, 0xff, 0x45, 0x09, 0xe0, 0x0e, 0x19, 0xd8, 0xee, - 0x7e, 0x9f, 0x38, 0x67, 0xc1, 0xa1, 0x36, 0x62, 0x1c, 0xea, 0xfa, 0x71, 0xcb, 0xa3, 0x5c, 0xcb, - 0x25, 0x51, 0x6f, 0x25, 0x48, 0x54, 0xbd, 0x38, 0xe4, 0xd1, 0x2c, 0xea, 0x6f, 0x65, 0xb8, 0x14, - 0x2a, 0x87, 0x34, 0xea, 0xc5, 0xd8, 0x1a, 0x7f, 0x35, 0xb1, 0xc6, 0xf3, 0x19, 0x26, 0x9f, 0x1b, - 0x8f, 0x7a, 0x17, 0x66, 0x18, 0xcb, 0x11, 0x6b, 0xc9, 0x39, 0xd4, 0xf8, 0xc8, 0x1c, 0x4a, 0x55, - 0xbb, 0xb5, 0x18, 0x12, 0x4e, 0x20, 0xe7, 0x70, 0xb6, 0x89, 0x2f, 0x22, 0x67, 0xfb, 0x50, 0x83, - 0x99, 0x70, 0x99, 0xce, 0x80, 0xb4, 0x35, 0xe3, 0xa4, 0xed, 0xc9, 0xc2, 0x21, 0x9a, 0xc3, 0xda, - 0xfe, 0xc5, 0x08, 0xbe, 0x52, 0x62, 0x1b, 0x7c, 0xcb, 0x30, 0x77, 0xd1, 0xe3, 0x30, 0xe6, 0x18, - 0xfd, 0x20, 0x32, 0xd5, 0x66, 0x69, 0x1a, 0x7d, 0x82, 0xb9, 0x04, 0xbd, 0xaf, 0x01, 0x92, 0x55, - 0xe0, 0xb6, 0xe3, 0xb8, 0xd4, 0x10, 0xb9, 0x52, 0xb8, 0xb5, 0x5a, 0xd8, 0xad, 0xa0, 0xc7, 0xda, - 0x66, 0x0a, 0xeb, 0xae, 0x43, 0xbd, 0xfd, 0x70, 0x91, 0xd3, 0x0a, 0x38, 0xc3, 0x01, 0x64, 0x00, - 0x78, 0x12, 0xb3, 0xe3, 0xca, 0x8d, 0x7c, 0xbd, 0x40, 0xce, 0x63, 0x06, 0x2b, 0xae, 0xb3, 0x6d, - 0xf5, 0xc2, 0xb4, 0x83, 0x15, 0x10, 0x8e, 0x80, 0x2e, 0xde, 0x85, 0xf9, 0x1c, 0x6f, 0xd1, 0x05, - 0x28, 0xef, 0x92, 0x7d, 0x31, 0x6d, 0x98, 0xfd, 0x89, 0xe6, 0xa0, 0xb2, 0x67, 0xd8, 0x43, 0x91, - 0x7e, 0x27, 0xb1, 0xf8, 0xf1, 0x42, 0xe9, 0x39, 0x4d, 0xff, 0xa0, 0x12, 0x8d, 0x1d, 0xce, 0x98, - 0xaf, 0x42, 0xd5, 0x23, 0x03, 0xdb, 0x32, 0x0d, 0x5f, 0x12, 0x21, 0x4e, 0x7e, 0xb1, 0x6c, 0xc3, - 0x4a, 0x1a, 0xe3, 0xd6, 0xa5, 0xcf, 0x97, 0x5b, 0x97, 0x4f, 0x87, 0x5b, 0x7f, 0x17, 0xaa, 0x7e, - 0xc0, 0xaa, 0xc7, 0x38, 0xe4, 0x8d, 0x11, 0xf2, 0xab, 0x24, 0xd4, 0xaa, 0x03, 0x45, 0xa5, 0x15, - 0x68, 0x16, 0x89, 0xae, 0x8c, 0x48, 0xa2, 0x4f, 0x95, 0xf8, 0xb2, 0x7c, 0x33, 0x30, 0x86, 0x3e, - 0xe9, 0xf2, 0xdc, 0x56, 0x0d, 0xf3, 0x4d, 0x8b, 0xb7, 0x62, 0x29, 0x45, 0xef, 0xc4, 0x42, 0xb6, - 0x7a, 0x92, 0x90, 0x9d, 0xc9, 0x0f, 0x57, 0xb4, 0x09, 0xf3, 0x03, 0xcf, 0xed, 0x79, 0xc4, 0xf7, - 0xef, 0x10, 0xa3, 0x6b, 0x5b, 0x0e, 0x09, 0xe6, 0x47, 0x30, 0xa2, 0x2b, 0x87, 0x07, 0xcb, 0xf3, - 0xad, 0x6c, 0x15, 0x9c, 0x67, 0xab, 0x3f, 0x18, 0x83, 0x0b, 0xc9, 0x0a, 0x98, 0x43, 0x52, 0xb5, - 0x13, 0x91, 0xd4, 0x6b, 0x91, 0xcd, 0x20, 0x18, 0xbc, 0x5a, 0xfd, 0x8c, 0x0d, 0x71, 0x1b, 0x66, - 0x65, 0x36, 0x08, 0x84, 0x92, 0xa6, 0xab, 0xd5, 0xdf, 0x8c, 0x8b, 0x71, 0x52, 0x1f, 0xbd, 0x08, - 0xd3, 0x1e, 0xe7, 0xdd, 0x01, 0x80, 0xe0, 0xae, 0x8f, 0x48, 0x80, 0x69, 0x1c, 0x15, 0xe2, 0xb8, - 0x2e, 0xe3, 0xad, 0x21, 0x1d, 0x0d, 0x00, 0xc6, 0xe2, 0xbc, 0xf5, 0x76, 0x52, 0x01, 0xa7, 0x6d, - 0xd0, 0x3a, 0x5c, 0x1a, 0x3a, 0x69, 0x28, 0x11, 0xca, 0x57, 0x24, 0xd4, 0xa5, 0xcd, 0xb4, 0x0a, - 0xce, 0xb2, 0x43, 0xdb, 0x31, 0x2a, 0x3b, 0xce, 0xd3, 0xf3, 0xcd, 0xc2, 0x1b, 0xaf, 0x30, 0x97, - 0xcd, 0xa0, 0xdb, 0xd5, 0xa2, 0x74, 0x5b, 0xff, 0x83, 0x16, 0x2d, 0x42, 0x8a, 0x02, 0x1f, 0x77, - 0xcb, 0x94, 0xb2, 0x88, 0xb0, 0x23, 0x37, 0x9b, 0xfd, 0xde, 0x1a, 0x89, 0xfd, 0x86, 0xc5, 0xf3, - 0x78, 0xfa, 0xfb, 0x47, 0x0d, 0x66, 0xef, 0x75, 0x3a, 0xad, 0x55, 0x87, 0xef, 0x96, 0x96, 0x41, - 0x77, 0x58, 0x15, 0x1d, 0x18, 0x74, 0x27, 0x59, 0x45, 0x99, 0x0c, 0x73, 0x09, 0x7a, 0x06, 0xaa, - 0xec, 0x5f, 0xe6, 0x38, 0x0f, 0xd7, 0x49, 0x9e, 0x64, 0xaa, 0x2d, 0xd9, 0xf6, 0x30, 0xf2, 0x37, - 0x56, 0x9a, 0xe8, 0x5b, 0x30, 0xc1, 0xf6, 0x36, 0x71, 0xba, 0x05, 0xc9, 0xaf, 0x74, 0xaa, 0x21, - 0x8c, 0x42, 0x3e, 0x23, 0x1b, 0x70, 0x00, 0xa7, 0xef, 0xc2, 0x5c, 0x64, 0x10, 0x78, 0x68, 0x93, - 0x37, 0x59, 0xbd, 0x42, 0x6d, 0xa8, 0xb0, 0xde, 0x59, 0x55, 0x2a, 0x17, 0xb8, 0x5e, 0x4c, 0x4c, - 0x44, 0xc8, 0x3d, 0xd8, 0x2f, 0x1f, 0x0b, 0x2c, 0x7d, 0x03, 0x26, 0x56, 0x5b, 0x0d, 0xdb, 0x15, - 0x7c, 0xc3, 0xb4, 0xba, 0x5e, 0x72, 0xa6, 0x56, 0x56, 0xef, 0x60, 0xcc, 0x25, 0x48, 0x87, 0x71, - 0x72, 0xdf, 0x24, 0x03, 0xca, 0x29, 0xc6, 0x64, 0x03, 0x58, 0x22, 0xbd, 0xcb, 0x5b, 0xb0, 0x94, - 0xe8, 0x3f, 0x29, 0xc1, 0x84, 0xec, 0xf6, 0x0c, 0xce, 0x1f, 0x6b, 0xb1, 0xf3, 0xc7, 0x53, 0xc5, - 0x96, 0x20, 0xf7, 0xf0, 0xd1, 0x49, 0x1c, 0x3e, 0xae, 0x15, 0xc4, 0x3b, 0xfa, 0xe4, 0xf1, 0x5e, - 0x09, 0x66, 0xe2, 0x8b, 0x8f, 0x9e, 0x85, 0x29, 0x96, 0x6a, 0x2d, 0x93, 0x34, 0x43, 0x86, 0xa7, - 0xae, 0x1f, 0xda, 0xa1, 0x08, 0x47, 0xf5, 0x50, 0x4f, 0x99, 0xb5, 0x5c, 0x8f, 0xca, 0x41, 0xe7, - 0x4f, 0xe9, 0x90, 0x5a, 0x76, 0x4d, 0x5c, 0xb6, 0xd7, 0x56, 0x1d, 0xba, 0xe1, 0xb5, 0xa9, 0x67, - 0x39, 0xbd, 0x54, 0x47, 0x0c, 0x0c, 0x47, 0x91, 0xd1, 0x5b, 0x2c, 0xed, 0xfb, 0xee, 0xd0, 0x33, - 0x49, 0x16, 0x7d, 0x0b, 0xa8, 0x07, 0xdb, 0x08, 0xdd, 0x35, 0xd7, 0x34, 0x6c, 0xb1, 0x38, 0x98, - 0x6c, 0x13, 0x8f, 0x38, 0x26, 0x09, 0x28, 0x93, 0x80, 0xc0, 0x0a, 0x4c, 0xff, 0xad, 0x06, 0x53, - 0x72, 0x2e, 0xce, 0x80, 0xa8, 0xbf, 0x1e, 0x27, 0xea, 0x4f, 0x14, 0xdc, 0xa1, 0xd9, 0x2c, 0xfd, - 0x77, 0x1a, 0x2c, 0x06, 0xae, 0xbb, 0x46, 0xb7, 0x61, 0xd8, 0x86, 0x63, 0x12, 0x2f, 0x88, 0xf5, - 0x45, 0x28, 0x59, 0x03, 0xb9, 0x92, 0x20, 0x01, 0x4a, 0xab, 0x2d, 0x5c, 0xb2, 0x06, 0xac, 0x8a, - 0xee, 0xb8, 0x3e, 0xe5, 0x6c, 0x5e, 0x1c, 0x14, 0x95, 0xd7, 0xf7, 0x64, 0x3b, 0x56, 0x1a, 0x68, - 0x13, 0x2a, 0x03, 0xd7, 0xa3, 0xac, 0x72, 0x95, 0x13, 0xeb, 0x7b, 0x84, 0xd7, 0x6c, 0xdd, 0x64, - 0x20, 0x86, 0x3b, 0x9d, 0xc1, 0x60, 0x81, 0xa6, 0xff, 0x50, 0x83, 0x47, 0x33, 0xfc, 0x97, 0xa4, - 0xa1, 0x0b, 0x13, 0x96, 0x10, 0xca, 0xf4, 0xf2, 0x7c, 0xb1, 0x6e, 0x33, 0xa6, 0x22, 0x4c, 0x6d, - 0x41, 0x0a, 0x0b, 0xa0, 0xf5, 0x5f, 0x69, 0x70, 0x31, 0xe5, 0x2f, 0x4f, 0xd1, 0x2c, 0x9e, 0x25, - 0xdb, 0x56, 0x29, 0x9a, 0x85, 0x25, 0x97, 0xa0, 0xd7, 0xa1, 0xca, 0xdf, 0x88, 0x4c, 0xd7, 0x96, - 0x13, 0x58, 0x0f, 0x26, 0xb0, 0x25, 0xdb, 0x1f, 0x1e, 0x2c, 0x5f, 0xc9, 0x38, 0x6b, 0x07, 0x62, - 0xac, 0x00, 0xd0, 0x32, 0x54, 0x88, 0xe7, 0xb9, 0x9e, 0x4c, 0xf6, 0x93, 0x6c, 0xa6, 0xee, 0xb2, - 0x06, 0x2c, 0xda, 0xf5, 0x5f, 0x87, 0x41, 0xca, 0xb2, 0x2f, 0xf3, 0x8f, 0x2d, 0x4e, 0x32, 0x31, - 0xb2, 0xa5, 0xc3, 0x5c, 0x82, 0x86, 0x70, 0xc1, 0x4a, 0xa4, 0x6b, 0xb9, 0x3b, 0xeb, 0xc5, 0xa6, - 0x51, 0x99, 0x35, 0x16, 0x24, 0xfc, 0x85, 0xa4, 0x04, 0xa7, 0xba, 0xd0, 0x09, 0xa4, 0xb4, 0xd0, - 0x1b, 0x30, 0xb6, 0x43, 0xe9, 0x20, 0xe3, 0xb2, 0xff, 0x98, 0x22, 0x11, 0xba, 0x50, 0xe5, 0xa3, - 0xeb, 0x74, 0x5a, 0x98, 0x43, 0xe9, 0xbf, 0x2f, 0xa9, 0xf9, 0xe0, 0x27, 0xa4, 0x6f, 0xaa, 0xd1, - 0xae, 0xd8, 0x86, 0xef, 0xf3, 0x14, 0x26, 0x4e, 0xf3, 0x73, 0x11, 0xc7, 0x95, 0x0c, 0xa7, 0xb4, - 0x51, 0x27, 0x2c, 0x9e, 0xda, 0x49, 0x8a, 0xe7, 0x54, 0x56, 0xe1, 0x44, 0xf7, 0xa0, 0x4c, 0xed, - 0xa2, 0xa7, 0x72, 0x89, 0xd8, 0x59, 0x6b, 0x37, 0xa6, 0xe4, 0x94, 0x97, 0x3b, 0x6b, 0x6d, 0xcc, - 0x20, 0xd0, 0x06, 0x54, 0xbc, 0xa1, 0x4d, 0x58, 0x1d, 0x28, 0x17, 0xaf, 0x2b, 0x6c, 0x06, 0xc3, - 0xcd, 0xc7, 0x7e, 0xf9, 0x58, 0xe0, 0xe8, 0x3f, 0xd2, 0x60, 0x3a, 0x56, 0x2d, 0x90, 0x07, 0xe7, - 0xed, 0xc8, 0xde, 0x91, 0xf3, 0xf0, 0xdc, 0xe8, 0xbb, 0x4e, 0x6e, 0xfa, 0x39, 0xd9, 0xef, 0xf9, - 0xa8, 0x0c, 0xc7, 0xfa, 0xd0, 0x0d, 0x80, 0x70, 0xd8, 0x6c, 0x1f, 0xb0, 0xe0, 0x15, 0x1b, 0x5e, - 0xee, 0x03, 0x16, 0xd3, 0x3e, 0x16, 0xed, 0xe8, 0x26, 0x80, 0x4f, 0x4c, 0x8f, 0xd0, 0x66, 0x98, - 0xb8, 0x54, 0x39, 0x6e, 0x2b, 0x09, 0x8e, 0x68, 0xe9, 0x7f, 0xd2, 0x60, 0xba, 0x49, 0xe8, 0xf7, - 0x5d, 0x6f, 0xb7, 0xe5, 0xda, 0x96, 0xb9, 0x7f, 0x06, 0x24, 0x00, 0xc7, 0x48, 0xc0, 0x71, 0xf9, - 0x32, 0xe6, 0x5d, 0x1e, 0x15, 0xd0, 0x3f, 0xd4, 0x60, 0x3e, 0xa6, 0x79, 0x37, 0xcc, 0x07, 0x2a, - 0x41, 0x6b, 0x85, 0x12, 0x74, 0x0c, 0x86, 0x25, 0xb5, 0xec, 0x04, 0x8d, 0xd6, 0xa0, 0x44, 0x5d, - 0x19, 0xbd, 0xa3, 0x61, 0x12, 0xe2, 0x85, 0x35, 0xa7, 0xe3, 0xe2, 0x12, 0x75, 0xd9, 0x42, 0x2c, - 0xc4, 0xb4, 0xa2, 0x19, 0xed, 0x73, 0x1a, 0x01, 0x86, 0xb1, 0x6d, 0xcf, 0xed, 0x9f, 0x78, 0x0c, - 0x6a, 0x21, 0x5e, 0xf1, 0xdc, 0x3e, 0xe6, 0x58, 0xfa, 0x47, 0x1a, 0x5c, 0x8c, 0x69, 0x9e, 0x01, - 0x6f, 0x78, 0x23, 0xce, 0x1b, 0xae, 0x8d, 0x32, 0x90, 0x1c, 0xf6, 0xf0, 0x51, 0x29, 0x31, 0x0c, - 0x36, 0x60, 0xb4, 0x0d, 0x53, 0x03, 0xb7, 0xdb, 0x3e, 0x85, 0x07, 0xda, 0x59, 0xc6, 0xe7, 0x5a, - 0x21, 0x16, 0x8e, 0x02, 0xa3, 0xfb, 0x70, 0x91, 0x51, 0x0b, 0x7f, 0x60, 0x98, 0xa4, 0x7d, 0x0a, - 0x57, 0x56, 0x8f, 0xf0, 0x17, 0xa0, 0x24, 0x22, 0x4e, 0x77, 0x82, 0xd6, 0x61, 0xc2, 0x1a, 0xf0, - 0xf3, 0x85, 0x24, 0x92, 0xc7, 0x92, 0x30, 0x71, 0x1a, 0x11, 0x29, 0x5e, 0xfe, 0xc0, 0x01, 0x86, - 0xfe, 0xd7, 0x64, 0x34, 0x70, 0xba, 0xfa, 0x6a, 0x84, 0x1e, 0xc8, 0xb7, 0x9a, 0x93, 0x51, 0x83, - 0xa6, 0x64, 0x22, 0x27, 0x65, 0xd6, 0xd5, 0x04, 0x6f, 0xf9, 0x0a, 0x4c, 0x10, 0xa7, 0xcb, 0xc9, - 0xba, 0xb8, 0x08, 0xe1, 0xa3, 0xba, 0x2b, 0x9a, 0x70, 0x20, 0xd3, 0x7f, 0x5c, 0x4e, 0x8c, 0x8a, - 0x97, 0xd9, 0x77, 0x4f, 0x2d, 0x38, 0x14, 0xe1, 0xcf, 0x0d, 0x90, 0xad, 0x90, 0xfe, 0x89, 0x98, - 0xff, 0xc6, 0x28, 0x31, 0x1f, 0xad, 0x7f, 0xb9, 0xe4, 0x0f, 0x7d, 0x07, 0xc6, 0x89, 0xe8, 0x42, - 0x54, 0xd5, 0x5b, 0xa3, 0x74, 0x11, 0xa6, 0xdf, 0xf0, 0x9c, 0x25, 0xdb, 0x24, 0x2a, 0x7a, 0x99, - 0xcd, 0x17, 0xd3, 0x65, 0xc7, 0x12, 0xc1, 0x9e, 0x27, 0x1b, 0x8f, 0x89, 0x61, 0xab, 0xe6, 0x87, - 0x07, 0xcb, 0x10, 0xfe, 0xc4, 0x51, 0x0b, 0xfe, 0x7a, 0x26, 0xef, 0x6c, 0xce, 0xe6, 0x0b, 0xa4, - 0xd1, 0x5e, 0xcf, 0x42, 0xd7, 0x4e, 0xed, 0xf5, 0x2c, 0x02, 0x79, 0xf4, 0x19, 0xf6, 0x9f, 0x25, - 0xb8, 0x14, 0x2a, 0x17, 0x7e, 0x3d, 0xcb, 0x30, 0xf9, 0xff, 0x57, 0x48, 0xc5, 0x5e, 0xb4, 0xc2, - 0xa9, 0xfb, 0xef, 0x7b, 0xd1, 0x0a, 0x7d, 0xcb, 0xa9, 0x76, 0xbf, 0x29, 0x45, 0x07, 0x30, 0xe2, - 0xb3, 0xca, 0x29, 0x7c, 0x88, 0xf3, 0x85, 0x7b, 0x99, 0xd1, 0xff, 0x52, 0x86, 0x0b, 0xc9, 0xdd, - 0x18, 0xbb, 0x7d, 0xd7, 0x8e, 0xbd, 0x7d, 0x6f, 0xc1, 0xdc, 0xf6, 0xd0, 0xb6, 0xf7, 0xf9, 0x18, - 0x22, 0x57, 0xf0, 0xe2, 0xde, 0xfe, 0x4b, 0xd2, 0x72, 0xee, 0x95, 0x0c, 0x1d, 0x9c, 0x69, 0x99, - 0xbe, 0x8c, 0x1f, 0xfb, 0x4f, 0x2f, 0xe3, 0x2b, 0x27, 0xb8, 0x8c, 0xcf, 0x7e, 0xcf, 0x28, 0x9f, - 0xe8, 0x3d, 0xe3, 0x24, 0x37, 0xf1, 0x19, 0x49, 0xec, 0xd8, 0xaf, 0x4a, 0x5e, 0x82, 0x99, 0xf8, - 0xeb, 0x90, 0x58, 0x4b, 0xf1, 0x40, 0x25, 0xdf, 0x62, 0x22, 0x6b, 0x29, 0xda, 0xb1, 0xd2, 0xd0, - 0x0f, 0x35, 0xb8, 0x9c, 0xfd, 0x15, 0x08, 0xb2, 0x61, 0xa6, 0x6f, 0xdc, 0x8f, 0x7e, 0x99, 0xa3, - 0x9d, 0x90, 0xad, 0xf0, 0x67, 0x81, 0xf5, 0x18, 0x16, 0x4e, 0x60, 0xa3, 0xb7, 0xa1, 0xda, 0x37, - 0xee, 0xb7, 0x87, 0x5e, 0x8f, 0x9c, 0x98, 0x15, 0xf1, 0x6d, 0xb4, 0x2e, 0x51, 0xb0, 0xc2, 0xd3, - 0x3f, 0xd3, 0x60, 0x3e, 0xe7, 0xb2, 0xff, 0x7f, 0x68, 0x94, 0xef, 0x95, 0xa0, 0xd2, 0x36, 0x0d, - 0x9b, 0x9c, 0x01, 0xa1, 0x78, 0x2d, 0x46, 0x28, 0x8e, 0xfb, 0x9a, 0x94, 0x7b, 0x95, 0xcb, 0x25, - 0x70, 0x82, 0x4b, 0x3c, 0x55, 0x08, 0xed, 0x68, 0x1a, 0xf1, 0x3c, 0x4c, 0xaa, 0x4e, 0x47, 0xcb, - 0x6e, 0xfa, 0x2f, 0x4b, 0x30, 0x15, 0xe9, 0x62, 0xc4, 0xdc, 0xb8, 0x1d, 0x2b, 0x08, 0xe5, 0x02, - 0x37, 0x2d, 0x91, 0xbe, 0x6a, 0x41, 0x09, 0x10, 0x5f, 0x43, 0x84, 0xef, 0xdf, 0xe9, 0xca, 0xf0, - 0x12, 0xcc, 0x50, 0xc3, 0xeb, 0x11, 0xaa, 0x68, 0xbb, 0xb8, 0x64, 0x54, 0x9f, 0xe5, 0x74, 0x62, - 0x52, 0x9c, 0xd0, 0x5e, 0x7c, 0x11, 0xa6, 0x63, 0x9d, 0x8d, 0xf2, 0x31, 0x43, 0x63, 0xe5, 0xc1, - 0xa7, 0x4b, 0xe7, 0x3e, 0xfe, 0x74, 0xe9, 0xdc, 0x27, 0x9f, 0x2e, 0x9d, 0xfb, 0xc1, 0xe1, 0x92, - 0xf6, 0xe0, 0x70, 0x49, 0xfb, 0xf8, 0x70, 0x49, 0xfb, 0xe4, 0x70, 0x49, 0xfb, 0xfb, 0xe1, 0x92, - 0xf6, 0xd3, 0xcf, 0x96, 0xce, 0xbd, 0xfd, 0xd8, 0x91, 0xff, 0xb7, 0xe1, 0xdf, 0x01, 0x00, 0x00, - 0xff, 0xff, 0x5f, 0xd8, 0x14, 0x50, 0xfb, 0x30, 0x00, 0x00, + // 2875 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x5b, 0xcf, 0x6f, 0x24, 0x47, + 0xf5, 0xdf, 0x9e, 0xf1, 0xd8, 0xe3, 0xe7, 0xb5, 0xbd, 0x5b, 0xeb, 0xac, 0x1d, 0xef, 0x37, 0x76, + 0xd4, 0x5f, 0x11, 0x36, 0x61, 0x77, 0x86, 0xdd, 0x24, 0x4b, 0x7e, 0x48, 0x09, 0x3b, 0xde, 0x4d, + 0xd6, 0x89, 0x7f, 0x4c, 0x6a, 0xc6, 0x09, 0x8a, 0x08, 0xd0, 0xee, 0x29, 0x8f, 0x3b, 0xee, 0xe9, + 0x1e, 0x75, 0xd7, 0x98, 0xf5, 0x0d, 0x04, 0x97, 0x9c, 0x40, 0x42, 0x21, 0x1c, 0x91, 0x90, 0xb8, + 0x72, 0xe5, 0x10, 0x22, 0x10, 0x41, 0x8a, 0x38, 0x45, 0xe2, 0x40, 0x4e, 0x16, 0x71, 0x4e, 0x88, + 0x7f, 0x00, 0xed, 0x09, 0xd5, 0x8f, 0xae, 0xfe, 0x6d, 0xf7, 0x0c, 0x5e, 0x8b, 0x20, 0x4e, 0xeb, + 0xa9, 0xf7, 0xde, 0xa7, 0x5e, 0x55, 0xbd, 0x7a, 0xef, 0x53, 0x55, 0xbd, 0x70, 0x7d, 0xef, 0x39, + 0xbf, 0x66, 0xb9, 0x75, 0xa3, 0x6f, 0xd5, 0xc9, 0x7d, 0x4a, 0x1c, 0xdf, 0x72, 0x1d, 0xbf, 0xbe, + 0x7f, 0x63, 0x9b, 0x50, 0xe3, 0x46, 0xbd, 0x4b, 0x1c, 0xe2, 0x19, 0x94, 0x74, 0x6a, 0x7d, 0xcf, + 0xa5, 0x2e, 0x7a, 0x4c, 0xa8, 0xd7, 0x8c, 0xbe, 0x55, 0x0b, 0xd5, 0x6b, 0x52, 0x7d, 0xf1, 0x7a, + 0xd7, 0xa2, 0xbb, 0x83, 0xed, 0x9a, 0xe9, 0xf6, 0xea, 0x5d, 0xb7, 0xeb, 0xd6, 0xb9, 0xd5, 0xf6, + 0x60, 0x87, 0xff, 0xe2, 0x3f, 0xf8, 0x5f, 0x02, 0x6d, 0x51, 0x8f, 0x74, 0x6e, 0xba, 0x1e, 0xa9, + 0xef, 0xa7, 0x7a, 0x5c, 0x7c, 0x26, 0xd4, 0xe9, 0x19, 0xe6, 0xae, 0xe5, 0x10, 0xef, 0xa0, 0xde, + 0xdf, 0xeb, 0xb2, 0x06, 0xbf, 0xde, 0x23, 0xd4, 0xc8, 0xb2, 0xaa, 0xe7, 0x59, 0x79, 0x03, 0x87, + 0x5a, 0x3d, 0x92, 0x32, 0xb8, 0x75, 0x92, 0x81, 0x6f, 0xee, 0x92, 0x9e, 0x91, 0xb2, 0x7b, 0x3a, + 0xcf, 0x6e, 0x40, 0x2d, 0xbb, 0x6e, 0x39, 0xd4, 0xa7, 0x5e, 0xd2, 0x48, 0x7f, 0xbf, 0x04, 0x93, + 0x77, 0x0c, 0xd2, 0x73, 0x9d, 0x16, 0xa1, 0xe8, 0x7b, 0x50, 0x65, 0xc3, 0xe8, 0x18, 0xd4, 0x58, + 0xd0, 0x1e, 0xd7, 0xae, 0x4e, 0xdd, 0xfc, 0x7a, 0x2d, 0x9c, 0x66, 0x85, 0x5a, 0xeb, 0xef, 0x75, + 0x59, 0x83, 0x5f, 0x63, 0xda, 0xb5, 0xfd, 0x1b, 0xb5, 0xcd, 0xed, 0x77, 0x89, 0x49, 0xd7, 0x09, + 0x35, 0x1a, 0xe8, 0x93, 0xc3, 0xe5, 0x73, 0x47, 0x87, 0xcb, 0x10, 0xb6, 0x61, 0x85, 0x8a, 0x36, + 0x60, 0xcc, 0xef, 0x13, 0x73, 0xa1, 0xc4, 0xd1, 0xaf, 0xd5, 0x8e, 0x5d, 0xc4, 0x9a, 0xf2, 0xac, + 0xd5, 0x27, 0x66, 0xe3, 0xbc, 0x44, 0x1e, 0x63, 0xbf, 0x30, 0xc7, 0x41, 0x6f, 0xc2, 0xb8, 0x4f, + 0x0d, 0x3a, 0xf0, 0x17, 0xca, 0x1c, 0xb1, 0x56, 0x18, 0x91, 0x5b, 0x35, 0x66, 0x24, 0xe6, 0xb8, + 0xf8, 0x8d, 0x25, 0x9a, 0xfe, 0xf7, 0x12, 0x20, 0xa5, 0xbb, 0xe2, 0x3a, 0x1d, 0x8b, 0x5a, 0xae, + 0x83, 0x5e, 0x80, 0x31, 0x7a, 0xd0, 0x27, 0x7c, 0x72, 0x26, 0x1b, 0x4f, 0x04, 0x0e, 0xb5, 0x0f, + 0xfa, 0xe4, 0xc1, 0xe1, 0xf2, 0xe5, 0xb4, 0x05, 0x93, 0x60, 0x6e, 0x83, 0xd6, 0x94, 0xab, 0x25, + 0x6e, 0xfd, 0x4c, 0xbc, 0xeb, 0x07, 0x87, 0xcb, 0x19, 0x41, 0x58, 0x53, 0x48, 0x71, 0x07, 0xd1, + 0x3e, 0x20, 0xdb, 0xf0, 0x69, 0xdb, 0x33, 0x1c, 0x5f, 0xf4, 0x64, 0xf5, 0x88, 0x9c, 0x84, 0xa7, + 0x8a, 0x2d, 0x1a, 0xb3, 0x68, 0x2c, 0x4a, 0x2f, 0xd0, 0x5a, 0x0a, 0x0d, 0x67, 0xf4, 0x80, 0x9e, + 0x80, 0x71, 0x8f, 0x18, 0xbe, 0xeb, 0x2c, 0x8c, 0xf1, 0x51, 0xa8, 0x09, 0xc4, 0xbc, 0x15, 0x4b, + 0x29, 0x7a, 0x12, 0x26, 0x7a, 0xc4, 0xf7, 0x8d, 0x2e, 0x59, 0xa8, 0x70, 0xc5, 0x59, 0xa9, 0x38, + 0xb1, 0x2e, 0x9a, 0x71, 0x20, 0xd7, 0x3f, 0xd4, 0x60, 0x5a, 0xcd, 0xdc, 0x9a, 0xe5, 0x53, 0xf4, + 0xed, 0x54, 0x1c, 0xd6, 0x8a, 0x0d, 0x89, 0x59, 0xf3, 0x28, 0xbc, 0x20, 0x7b, 0xab, 0x06, 0x2d, + 0x91, 0x18, 0x5c, 0x87, 0x8a, 0x45, 0x49, 0x8f, 0xad, 0x43, 0xf9, 0xea, 0xd4, 0xcd, 0xab, 0x45, + 0x43, 0xa6, 0x31, 0x2d, 0x41, 0x2b, 0xab, 0xcc, 0x1c, 0x0b, 0x14, 0xfd, 0xe7, 0x63, 0x11, 0xf7, + 0x59, 0x68, 0xa2, 0x77, 0xa0, 0xea, 0x13, 0x9b, 0x98, 0xd4, 0xf5, 0xa4, 0xfb, 0x4f, 0x17, 0x74, + 0xdf, 0xd8, 0x26, 0x76, 0x4b, 0x9a, 0x36, 0xce, 0x33, 0xff, 0x83, 0x5f, 0x58, 0x41, 0xa2, 0x37, + 0xa0, 0x4a, 0x49, 0xaf, 0x6f, 0x1b, 0x94, 0xc8, 0x7d, 0xf4, 0xff, 0xd1, 0x21, 0xb0, 0xc8, 0x61, + 0x60, 0x4d, 0xb7, 0xd3, 0x96, 0x6a, 0x7c, 0xfb, 0xa8, 0x29, 0x09, 0x5a, 0xb1, 0x82, 0x41, 0xfb, + 0x30, 0x33, 0xe8, 0x77, 0x98, 0x26, 0x65, 0xd9, 0xa1, 0x7b, 0x20, 0x23, 0xe9, 0x56, 0xd1, 0xb9, + 0xd9, 0x8a, 0x59, 0x37, 0x2e, 0xcb, 0xbe, 0x66, 0xe2, 0xed, 0x38, 0xd1, 0x0b, 0xba, 0x0d, 0xb3, + 0x3d, 0xcb, 0xc1, 0xc4, 0xe8, 0x1c, 0xb4, 0x88, 0xe9, 0x3a, 0x1d, 0x9f, 0x87, 0x55, 0xa5, 0x31, + 0x2f, 0x01, 0x66, 0xd7, 0xe3, 0x62, 0x9c, 0xd4, 0x47, 0xaf, 0x01, 0x0a, 0x86, 0xf1, 0xaa, 0x48, + 0x6e, 0x96, 0xeb, 0xf0, 0x98, 0x2b, 0x87, 0xc1, 0xdd, 0x4e, 0x69, 0xe0, 0x0c, 0x2b, 0xb4, 0x06, + 0x73, 0x1e, 0xd9, 0xb7, 0xd8, 0x18, 0xef, 0x59, 0x3e, 0x75, 0xbd, 0x83, 0x35, 0xab, 0x67, 0xd1, + 0x85, 0x71, 0xee, 0xd3, 0xc2, 0xd1, 0xe1, 0xf2, 0x1c, 0xce, 0x90, 0xe3, 0x4c, 0x2b, 0xfd, 0x83, + 0x71, 0x98, 0x4d, 0xe4, 0x1b, 0xf4, 0x26, 0x5c, 0x36, 0x07, 0x9e, 0x47, 0x1c, 0xba, 0x31, 0xe8, + 0x6d, 0x13, 0xaf, 0x65, 0xee, 0x92, 0xce, 0xc0, 0x26, 0x1d, 0x1e, 0x28, 0x95, 0xc6, 0x92, 0xf4, + 0xf8, 0xf2, 0x4a, 0xa6, 0x16, 0xce, 0xb1, 0x66, 0xb3, 0xe0, 0xf0, 0xa6, 0x75, 0xcb, 0xf7, 0x15, + 0x66, 0x89, 0x63, 0xaa, 0x59, 0xd8, 0x48, 0x69, 0xe0, 0x0c, 0x2b, 0xe6, 0x63, 0x87, 0xf8, 0x96, + 0x47, 0x3a, 0x49, 0x1f, 0xcb, 0x71, 0x1f, 0xef, 0x64, 0x6a, 0xe1, 0x1c, 0x6b, 0xf4, 0x2c, 0x4c, + 0x89, 0xde, 0xf8, 0xfa, 0xc9, 0x85, 0xbe, 0x24, 0xc1, 0xa6, 0x36, 0x42, 0x11, 0x8e, 0xea, 0xb1, + 0xa1, 0xb9, 0xdb, 0x3e, 0xf1, 0xf6, 0x49, 0x27, 0x7f, 0x81, 0x37, 0x53, 0x1a, 0x38, 0xc3, 0x8a, + 0x0d, 0x4d, 0x44, 0x60, 0x6a, 0x68, 0xe3, 0xf1, 0xa1, 0x6d, 0x65, 0x6a, 0xe1, 0x1c, 0x6b, 0x16, + 0xc7, 0xc2, 0xe5, 0xdb, 0xfb, 0x86, 0x65, 0x1b, 0xdb, 0x36, 0x59, 0x98, 0x88, 0xc7, 0xf1, 0x46, + 0x5c, 0x8c, 0x93, 0xfa, 0xe8, 0x55, 0xb8, 0x28, 0x9a, 0xb6, 0x1c, 0x43, 0x81, 0x54, 0x39, 0xc8, + 0xa3, 0x12, 0xe4, 0xe2, 0x46, 0x52, 0x01, 0xa7, 0x6d, 0xd0, 0x0b, 0x30, 0x63, 0xba, 0xb6, 0xcd, + 0xe3, 0x71, 0xc5, 0x1d, 0x38, 0x74, 0x61, 0x92, 0xa3, 0x20, 0xb6, 0x1f, 0x57, 0x62, 0x12, 0x9c, + 0xd0, 0x44, 0x04, 0xc0, 0x0c, 0x0a, 0x8e, 0xbf, 0x00, 0x3c, 0x3f, 0xde, 0x28, 0x9a, 0x03, 0x54, + 0xa9, 0x0a, 0x39, 0x80, 0x6a, 0xf2, 0x71, 0x04, 0x58, 0xff, 0xb3, 0x06, 0xf3, 0x39, 0xa9, 0x03, + 0xbd, 0x1c, 0x2b, 0xb1, 0x5f, 0x4b, 0x94, 0xd8, 0x2b, 0x39, 0x66, 0x91, 0x3a, 0xeb, 0xc0, 0xb4, + 0xc7, 0x46, 0xe5, 0x74, 0x85, 0x8a, 0xcc, 0x91, 0xcf, 0x9e, 0x30, 0x0c, 0x1c, 0xb5, 0x09, 0x73, + 0xfe, 0xc5, 0xa3, 0xc3, 0xe5, 0xe9, 0x98, 0x0c, 0xc7, 0xe1, 0xf5, 0x5f, 0x94, 0x00, 0xee, 0x90, + 0xbe, 0xed, 0x1e, 0xf4, 0x88, 0x73, 0x16, 0x1c, 0x6a, 0x33, 0xc6, 0xa1, 0xae, 0x9f, 0xb4, 0x3c, + 0xca, 0xb5, 0x5c, 0x12, 0xf5, 0x56, 0x82, 0x44, 0xd5, 0x8b, 0x43, 0x1e, 0xcf, 0xa2, 0xfe, 0x5a, + 0x86, 0x4b, 0xa1, 0x72, 0x48, 0xa3, 0x5e, 0x8c, 0xad, 0xf1, 0x57, 0x13, 0x6b, 0x3c, 0x9f, 0x61, + 0xf2, 0xd0, 0x78, 0xd4, 0xbb, 0x30, 0xc3, 0x58, 0x8e, 0x58, 0x4b, 0xce, 0xa1, 0xc6, 0x87, 0xe6, + 0x50, 0xaa, 0xda, 0xad, 0xc5, 0x90, 0x70, 0x02, 0x39, 0x87, 0xb3, 0x4d, 0x7c, 0x19, 0x39, 0xdb, + 0x47, 0x1a, 0xcc, 0x84, 0xcb, 0x74, 0x06, 0xa4, 0x6d, 0x23, 0x4e, 0xda, 0x9e, 0x2c, 0x1c, 0xa2, + 0x39, 0xac, 0xed, 0x9f, 0x8c, 0xe0, 0x2b, 0x25, 0xb6, 0xc1, 0xb7, 0x0d, 0x73, 0x0f, 0x3d, 0x0e, + 0x63, 0x8e, 0xd1, 0x0b, 0x22, 0x53, 0x6d, 0x96, 0x0d, 0xa3, 0x47, 0x30, 0x97, 0xa0, 0xf7, 0x35, + 0x40, 0xb2, 0x0a, 0xdc, 0x76, 0x1c, 0x97, 0x1a, 0x22, 0x57, 0x0a, 0xb7, 0x56, 0x0b, 0xbb, 0x15, + 0xf4, 0x58, 0xdb, 0x4a, 0x61, 0xdd, 0x75, 0xa8, 0x77, 0x10, 0x2e, 0x72, 0x5a, 0x01, 0x67, 0x38, + 0x80, 0x0c, 0x00, 0x4f, 0x62, 0xb6, 0x5d, 0xb9, 0x91, 0xaf, 0x17, 0xc8, 0x79, 0xcc, 0x60, 0xc5, + 0x75, 0x76, 0xac, 0x6e, 0x98, 0x76, 0xb0, 0x02, 0xc2, 0x11, 0xd0, 0xc5, 0xbb, 0x30, 0x9f, 0xe3, + 0x2d, 0xba, 0x00, 0xe5, 0x3d, 0x72, 0x20, 0xa6, 0x0d, 0xb3, 0x3f, 0xd1, 0x1c, 0x54, 0xf6, 0x0d, + 0x7b, 0x20, 0xd2, 0xef, 0x24, 0x16, 0x3f, 0x5e, 0x28, 0x3d, 0xa7, 0xe9, 0x1f, 0x56, 0xa2, 0xb1, + 0xc3, 0x19, 0xf3, 0x55, 0xa8, 0x7a, 0xa4, 0x6f, 0x5b, 0xa6, 0xe1, 0x4b, 0x22, 0xc4, 0xc9, 0x2f, + 0x96, 0x6d, 0x58, 0x49, 0x63, 0xdc, 0xba, 0xf4, 0x70, 0xb9, 0x75, 0xf9, 0x74, 0xb8, 0xf5, 0x77, + 0xa1, 0xea, 0x07, 0xac, 0x7a, 0x8c, 0x43, 0xde, 0x18, 0x22, 0xbf, 0x4a, 0x42, 0xad, 0x3a, 0x50, + 0x54, 0x5a, 0x81, 0x66, 0x91, 0xe8, 0xca, 0x90, 0x24, 0xfa, 0x54, 0x89, 0x2f, 0xcb, 0x37, 0x7d, + 0x63, 0xe0, 0x93, 0x0e, 0xcf, 0x6d, 0xd5, 0x30, 0xdf, 0x34, 0x79, 0x2b, 0x96, 0x52, 0xf4, 0x4e, + 0x2c, 0x64, 0xab, 0xa3, 0x84, 0xec, 0x4c, 0x7e, 0xb8, 0xa2, 0x2d, 0x98, 0xef, 0x7b, 0x6e, 0xd7, + 0x23, 0xbe, 0x7f, 0x87, 0x18, 0x1d, 0xdb, 0x72, 0x48, 0x30, 0x3f, 0x82, 0x11, 0x5d, 0x39, 0x3a, + 0x5c, 0x9e, 0x6f, 0x66, 0xab, 0xe0, 0x3c, 0x5b, 0xfd, 0x67, 0x15, 0xb8, 0x90, 0xac, 0x80, 0x39, + 0x24, 0x55, 0x1b, 0x89, 0xa4, 0x5e, 0x8b, 0x6c, 0x06, 0xc1, 0xe0, 0xd5, 0xea, 0x67, 0x6c, 0x88, + 0xdb, 0x30, 0x2b, 0xb3, 0x41, 0x20, 0x94, 0x34, 0x5d, 0xad, 0xfe, 0x56, 0x5c, 0x8c, 0x93, 0xfa, + 0xe8, 0x45, 0x98, 0xf6, 0x38, 0xef, 0x0e, 0x00, 0x04, 0x77, 0x7d, 0x44, 0x02, 0x4c, 0xe3, 0xa8, + 0x10, 0xc7, 0x75, 0x19, 0x6f, 0x0d, 0xe9, 0x68, 0x00, 0x30, 0x16, 0xe7, 0xad, 0xb7, 0x93, 0x0a, + 0x38, 0x6d, 0x83, 0xd6, 0xe1, 0xd2, 0xc0, 0x49, 0x43, 0x89, 0x50, 0xbe, 0x22, 0xa1, 0x2e, 0x6d, + 0xa5, 0x55, 0x70, 0x96, 0x1d, 0x5a, 0x85, 0x4b, 0x94, 0x78, 0x3d, 0xcb, 0x31, 0xa8, 0xe5, 0x74, + 0x15, 0x9c, 0x58, 0xf9, 0x79, 0x06, 0xd5, 0x4e, 0x8b, 0x71, 0x96, 0x0d, 0xda, 0x89, 0xb1, 0xe2, + 0x71, 0x9e, 0xe9, 0x6f, 0x16, 0xde, 0xc3, 0x85, 0x69, 0x71, 0x06, 0x73, 0xaf, 0x16, 0x65, 0xee, + 0xfa, 0x1f, 0xb4, 0x68, 0x3d, 0x53, 0x6c, 0xfa, 0xa4, 0x0b, 0xab, 0x94, 0x45, 0x84, 0x68, 0xb9, + 0xd9, 0x44, 0xfa, 0xd6, 0x50, 0x44, 0x3a, 0xac, 0xc3, 0x27, 0x33, 0xe9, 0x3f, 0x6a, 0x30, 0x7b, + 0xaf, 0xdd, 0x6e, 0xae, 0x3a, 0x7c, 0xe3, 0x35, 0x0d, 0xba, 0xcb, 0x0a, 0x72, 0xdf, 0xa0, 0xbb, + 0xc9, 0x82, 0xcc, 0x64, 0x98, 0x4b, 0xd0, 0x33, 0x50, 0x65, 0xff, 0x32, 0xc7, 0x79, 0xe4, 0x4f, + 0xf2, 0x7c, 0x55, 0x6d, 0xca, 0xb6, 0x07, 0x91, 0xbf, 0xb1, 0xd2, 0x44, 0xdf, 0x82, 0x09, 0x96, + 0x26, 0x88, 0xd3, 0x29, 0xc8, 0xa3, 0xa5, 0x53, 0x0d, 0x61, 0x14, 0x52, 0x23, 0xd9, 0x80, 0x03, + 0x38, 0x7d, 0x0f, 0xe6, 0x22, 0x83, 0xc0, 0x03, 0x9b, 0xbc, 0xc9, 0x4a, 0x1f, 0x6a, 0x41, 0x85, + 0xf5, 0xce, 0x0a, 0x5c, 0xb9, 0xc0, 0x4d, 0x65, 0x62, 0x22, 0x42, 0x1a, 0xc3, 0x7e, 0xf9, 0x58, + 0x60, 0xe9, 0x9b, 0x30, 0xb1, 0xda, 0x6c, 0xd8, 0xae, 0xa0, 0x2e, 0xa6, 0xd5, 0xf1, 0x92, 0x33, + 0xb5, 0xb2, 0x7a, 0x07, 0x63, 0x2e, 0x41, 0x3a, 0x8c, 0x93, 0xfb, 0x26, 0xe9, 0x53, 0xce, 0x56, + 0x26, 0x1b, 0xc0, 0x72, 0xf2, 0x5d, 0xde, 0x82, 0xa5, 0x44, 0xff, 0x49, 0x09, 0x26, 0x64, 0xb7, + 0x67, 0x70, 0x94, 0x59, 0x8b, 0x1d, 0x65, 0x9e, 0x2a, 0xb6, 0x04, 0xb9, 0xe7, 0x98, 0x76, 0xe2, + 0x1c, 0x73, 0xad, 0x20, 0xde, 0xf1, 0x87, 0x98, 0xf7, 0x4a, 0x30, 0x13, 0x5f, 0x7c, 0xf4, 0x2c, + 0x4c, 0xb1, 0xac, 0x6d, 0x99, 0x64, 0x23, 0x24, 0x8b, 0xea, 0x26, 0xa3, 0x15, 0x8a, 0x70, 0x54, + 0x0f, 0x75, 0x95, 0x59, 0xd3, 0xf5, 0xa8, 0x1c, 0x74, 0xfe, 0x94, 0x0e, 0xa8, 0x65, 0xd7, 0xc4, + 0xbd, 0x7d, 0x6d, 0xd5, 0xa1, 0x9b, 0x5e, 0x8b, 0x7a, 0x96, 0xd3, 0x4d, 0x75, 0xc4, 0xc0, 0x70, + 0x14, 0x19, 0xbd, 0xc5, 0x2a, 0x88, 0xef, 0x0e, 0x3c, 0x93, 0x64, 0x31, 0xc1, 0x80, 0xc5, 0xb0, + 0x8d, 0xd0, 0x59, 0x73, 0x4d, 0xc3, 0x16, 0x8b, 0x83, 0xc9, 0x0e, 0xf1, 0x88, 0x63, 0x92, 0x80, + 0x7d, 0x09, 0x08, 0xac, 0xc0, 0xf4, 0xdf, 0x6a, 0x30, 0x25, 0xe7, 0xe2, 0x0c, 0x38, 0xff, 0xeb, + 0x71, 0xce, 0xff, 0x44, 0xc1, 0x1d, 0x9a, 0x4d, 0xf8, 0x7f, 0xa7, 0xc1, 0x62, 0xe0, 0xba, 0x6b, + 0x74, 0x1a, 0x86, 0x6d, 0x38, 0x26, 0xf1, 0x82, 0x58, 0x5f, 0x84, 0x92, 0xd5, 0x97, 0x2b, 0x09, + 0x12, 0xa0, 0xb4, 0xda, 0xc4, 0x25, 0xab, 0xcf, 0x0a, 0xf2, 0xae, 0xeb, 0x53, 0x7e, 0x30, 0x10, + 0x67, 0x4e, 0xe5, 0xf5, 0x3d, 0xd9, 0x8e, 0x95, 0x06, 0xda, 0x82, 0x4a, 0xdf, 0xf5, 0x28, 0x2b, + 0x82, 0xe5, 0xc4, 0xfa, 0x1e, 0xe3, 0x35, 0x5b, 0x37, 0x19, 0x88, 0xe1, 0x4e, 0x67, 0x30, 0x58, + 0xa0, 0xe9, 0x3f, 0xd4, 0xe0, 0xd1, 0x0c, 0xff, 0x25, 0xff, 0xe8, 0xc0, 0x84, 0x25, 0x84, 0x32, + 0xbd, 0x3c, 0x5f, 0xac, 0xdb, 0x8c, 0xa9, 0x08, 0x53, 0x5b, 0x90, 0xc2, 0x02, 0x68, 0xfd, 0x57, + 0x1a, 0x5c, 0x4c, 0xf9, 0xcb, 0x53, 0x34, 0x8b, 0x67, 0x49, 0xdc, 0x55, 0x8a, 0x66, 0x61, 0xc9, + 0x25, 0xe8, 0x75, 0xa8, 0xf2, 0xe7, 0x26, 0xd3, 0xb5, 0xe5, 0x04, 0xd6, 0x83, 0x09, 0x6c, 0xca, + 0xf6, 0x07, 0x87, 0xcb, 0x57, 0x32, 0x8e, 0xed, 0x81, 0x18, 0x2b, 0x00, 0xb4, 0x0c, 0x15, 0xe2, + 0x79, 0xae, 0x27, 0x93, 0xfd, 0x24, 0x9b, 0xa9, 0xbb, 0xac, 0x01, 0x8b, 0x76, 0xfd, 0xd7, 0x61, + 0x90, 0xb2, 0xec, 0xcb, 0xfc, 0x63, 0x8b, 0x93, 0x4c, 0x8c, 0x6c, 0xe9, 0x30, 0x97, 0xa0, 0x01, + 0x5c, 0xb0, 0x12, 0xe9, 0x5a, 0xee, 0xce, 0x7a, 0xb1, 0x69, 0x54, 0x66, 0x8d, 0x05, 0x09, 0x7f, + 0x21, 0x29, 0xc1, 0xa9, 0x2e, 0x74, 0x02, 0x29, 0x2d, 0xf4, 0x06, 0x8c, 0xed, 0x52, 0xda, 0xcf, + 0x78, 0x37, 0x38, 0xa1, 0x48, 0x84, 0x2e, 0x54, 0xf9, 0xe8, 0xda, 0xed, 0x26, 0xe6, 0x50, 0xfa, + 0xef, 0x4b, 0x6a, 0x3e, 0xf8, 0x61, 0xeb, 0x9b, 0x6a, 0xb4, 0x2b, 0xb6, 0xe1, 0xfb, 0x3c, 0x85, + 0x89, 0x8b, 0x81, 0xb9, 0x88, 0xe3, 0x4a, 0x86, 0x53, 0xda, 0xa8, 0x1d, 0x16, 0x4f, 0x6d, 0x94, + 0xe2, 0x39, 0x95, 0x55, 0x38, 0xd1, 0x3d, 0x28, 0x53, 0xbb, 0xe8, 0x01, 0x5f, 0x22, 0xb6, 0xd7, + 0x5a, 0x8d, 0x29, 0x39, 0xe5, 0xe5, 0xf6, 0x5a, 0x0b, 0x33, 0x08, 0xb4, 0x09, 0x15, 0x6f, 0x60, + 0x13, 0x56, 0x07, 0xca, 0xc5, 0xeb, 0x0a, 0x9b, 0xc1, 0x70, 0xf3, 0xb1, 0x5f, 0x3e, 0x16, 0x38, + 0xfa, 0x8f, 0x34, 0x98, 0x8e, 0x55, 0x0b, 0xe4, 0xc1, 0x79, 0x3b, 0xb2, 0x77, 0xe4, 0x3c, 0x3c, + 0x37, 0xfc, 0xae, 0x93, 0x9b, 0x7e, 0x4e, 0xf6, 0x7b, 0x3e, 0x2a, 0xc3, 0xb1, 0x3e, 0x74, 0x03, + 0x20, 0x1c, 0x36, 0xdb, 0x07, 0x2c, 0x78, 0xc5, 0x86, 0x97, 0xfb, 0x80, 0xc5, 0xb4, 0x8f, 0x45, + 0x3b, 0xba, 0x09, 0xe0, 0x13, 0xd3, 0x23, 0x74, 0x23, 0x4c, 0x5c, 0xaa, 0x1c, 0xb7, 0x94, 0x04, + 0x47, 0xb4, 0xf4, 0x3f, 0x69, 0x30, 0xbd, 0x41, 0xe8, 0xf7, 0x5d, 0x6f, 0xaf, 0xe9, 0xda, 0x96, + 0x79, 0x70, 0x06, 0x24, 0x00, 0xc7, 0x48, 0xc0, 0x49, 0xf9, 0x32, 0xe6, 0x5d, 0x1e, 0x15, 0xd0, + 0x3f, 0xd2, 0x60, 0x3e, 0xa6, 0x79, 0x37, 0xcc, 0x07, 0x2a, 0x41, 0x6b, 0x85, 0x12, 0x74, 0x0c, + 0x86, 0x25, 0xb5, 0xec, 0x04, 0x8d, 0xd6, 0xa0, 0x44, 0x5d, 0x19, 0xbd, 0xc3, 0x61, 0x12, 0xe2, + 0x85, 0x35, 0xa7, 0xed, 0xe2, 0x12, 0x75, 0xd9, 0x42, 0x2c, 0xc4, 0xb4, 0xa2, 0x19, 0xed, 0x21, + 0x8d, 0x00, 0xc3, 0xd8, 0x8e, 0xe7, 0xf6, 0x46, 0x1e, 0x83, 0x5a, 0x88, 0x57, 0x3c, 0xb7, 0x87, + 0x39, 0x96, 0xfe, 0xb1, 0x06, 0x17, 0x63, 0x9a, 0x67, 0xc0, 0x1b, 0xde, 0x88, 0xf3, 0x86, 0x6b, + 0xc3, 0x0c, 0x24, 0x87, 0x3d, 0x7c, 0x5c, 0x4a, 0x0c, 0x83, 0x0d, 0x18, 0xed, 0xc0, 0x54, 0xdf, + 0xed, 0xb4, 0x4e, 0xe1, 0xad, 0x77, 0x96, 0xf1, 0xb9, 0x66, 0x88, 0x85, 0xa3, 0xc0, 0xe8, 0x3e, + 0x5c, 0x64, 0xd4, 0xc2, 0xef, 0x1b, 0x26, 0x69, 0x9d, 0xc2, 0xed, 0xd7, 0x23, 0xfc, 0x31, 0x29, + 0x89, 0x88, 0xd3, 0x9d, 0xa0, 0x75, 0x98, 0xb0, 0xfa, 0xfc, 0x7c, 0x21, 0x89, 0xe4, 0x89, 0x24, + 0x4c, 0x9c, 0x46, 0x44, 0x8a, 0x97, 0x3f, 0x70, 0x80, 0xa1, 0xff, 0x25, 0x19, 0x0d, 0x9c, 0xae, + 0xbe, 0x1a, 0xa1, 0x07, 0xf2, 0xd9, 0x67, 0x34, 0x6a, 0xb0, 0x21, 0x99, 0xc8, 0xa8, 0xcc, 0xba, + 0x9a, 0xe0, 0x2d, 0x5f, 0x81, 0x09, 0xe2, 0x74, 0x38, 0x59, 0x17, 0x77, 0x2a, 0x7c, 0x54, 0x77, + 0x45, 0x13, 0x0e, 0x64, 0xfa, 0x8f, 0xcb, 0x89, 0x51, 0xf1, 0x32, 0xfb, 0xee, 0xa9, 0x05, 0x87, + 0x22, 0xfc, 0xb9, 0x01, 0xb2, 0x1d, 0xd2, 0x3f, 0x11, 0xf3, 0xdf, 0x18, 0x26, 0xe6, 0xa3, 0xf5, + 0x2f, 0x97, 0xfc, 0xa1, 0xef, 0xc0, 0x38, 0x11, 0x5d, 0x88, 0xaa, 0x7a, 0x6b, 0x98, 0x2e, 0xc2, + 0xf4, 0x1b, 0x9e, 0xb3, 0x64, 0x9b, 0x44, 0x45, 0x2f, 0xb3, 0xf9, 0x62, 0xba, 0xec, 0x58, 0x22, + 0xd8, 0xf3, 0x64, 0xe3, 0x31, 0x31, 0x6c, 0xd5, 0xfc, 0xe0, 0x70, 0x19, 0xc2, 0x9f, 0x38, 0x6a, + 0xc1, 0x1f, 0xe2, 0xe4, 0x9d, 0xcd, 0xd9, 0x7c, 0xcc, 0x34, 0xdc, 0x43, 0x5c, 0xe8, 0xda, 0xa9, + 0x3d, 0xc4, 0x45, 0x20, 0x8f, 0x3f, 0xc3, 0xfe, 0xa3, 0x04, 0x97, 0x42, 0xe5, 0xc2, 0x0f, 0x71, + 0x19, 0x26, 0xff, 0xfb, 0xa0, 0xa9, 0xd8, 0xe3, 0x58, 0x38, 0x75, 0xff, 0x79, 0x8f, 0x63, 0xa1, + 0x6f, 0x39, 0xd5, 0xee, 0x37, 0xa5, 0xe8, 0x00, 0x86, 0x7c, 0xa1, 0x39, 0x85, 0x6f, 0x7a, 0xbe, + 0x74, 0x8f, 0x3c, 0xfa, 0x07, 0x63, 0x70, 0x21, 0xb9, 0x1b, 0x63, 0x17, 0xf9, 0xda, 0x89, 0x17, + 0xf9, 0x4d, 0x98, 0xdb, 0x19, 0xd8, 0xf6, 0x01, 0x1f, 0x43, 0xe4, 0x36, 0x5f, 0x3c, 0x01, 0xfc, + 0x9f, 0xb4, 0x9c, 0x7b, 0x25, 0x43, 0x07, 0x67, 0x5a, 0xa6, 0xef, 0xf5, 0xc7, 0xfe, 0xdd, 0x7b, + 0xfd, 0xca, 0x08, 0xf7, 0xfa, 0x39, 0x17, 0xf1, 0x13, 0x23, 0x5c, 0xc4, 0x67, 0xbf, 0xb2, 0x94, + 0x47, 0x7a, 0x65, 0x19, 0xe5, 0x52, 0x3f, 0x23, 0x1f, 0x9e, 0xf8, 0xad, 0xcb, 0x4b, 0x30, 0x13, + 0x7f, 0xb3, 0x12, 0x61, 0x21, 0x9e, 0xcd, 0xe4, 0x0b, 0x51, 0x24, 0x2c, 0x44, 0x3b, 0x56, 0x1a, + 0xfa, 0x91, 0x06, 0x97, 0xb3, 0xbf, 0x4d, 0x41, 0x36, 0xcc, 0xf4, 0x8c, 0xfb, 0xd1, 0xef, 0x85, + 0xb4, 0x11, 0x89, 0x0f, 0x7f, 0x61, 0x58, 0x8f, 0x61, 0xe1, 0x04, 0x36, 0x7a, 0x1b, 0xaa, 0x3d, + 0xe3, 0x7e, 0x6b, 0xe0, 0x75, 0xc9, 0xc8, 0x04, 0x8b, 0xef, 0xc8, 0x75, 0x89, 0x82, 0x15, 0x9e, + 0xfe, 0x85, 0x06, 0xf3, 0x39, 0xef, 0x06, 0xff, 0x45, 0xa3, 0x7c, 0xaf, 0x04, 0x95, 0x96, 0x69, + 0xd8, 0xe4, 0x0c, 0xb8, 0xc9, 0x6b, 0x31, 0x6e, 0x72, 0xd2, 0x37, 0xae, 0xdc, 0xab, 0x5c, 0x5a, + 0x82, 0x13, 0xb4, 0xe4, 0xa9, 0x42, 0x68, 0xc7, 0x33, 0x92, 0xe7, 0x61, 0x52, 0x75, 0x3a, 0x5c, + 0xa2, 0xd4, 0x7f, 0x59, 0x82, 0xa9, 0x48, 0x17, 0x43, 0xa6, 0xd9, 0x9d, 0x58, 0x6d, 0x29, 0x17, + 0xb8, 0xb4, 0x89, 0xf4, 0x55, 0x0b, 0xaa, 0x89, 0xf8, 0x46, 0x23, 0x7c, 0x95, 0x4f, 0x17, 0x99, + 0x97, 0x60, 0x86, 0x1a, 0x5e, 0x97, 0x50, 0x75, 0x02, 0x10, 0xf7, 0x95, 0xea, 0x63, 0xa1, 0x76, + 0x4c, 0x8a, 0x13, 0xda, 0x8b, 0x2f, 0xc2, 0x74, 0xac, 0xb3, 0x61, 0x3e, 0xb1, 0x68, 0xac, 0x7c, + 0xf2, 0xf9, 0xd2, 0xb9, 0x4f, 0x3f, 0x5f, 0x3a, 0xf7, 0xd9, 0xe7, 0x4b, 0xe7, 0x7e, 0x70, 0xb4, + 0xa4, 0x7d, 0x72, 0xb4, 0xa4, 0x7d, 0x7a, 0xb4, 0xa4, 0x7d, 0x76, 0xb4, 0xa4, 0xfd, 0xed, 0x68, + 0x49, 0xfb, 0xe9, 0x17, 0x4b, 0xe7, 0xde, 0x7e, 0xec, 0xd8, 0xff, 0x71, 0xf1, 0xaf, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x6a, 0x79, 0xb9, 0xab, 0x91, 0x31, 0x00, 0x00, } func (m *DaemonSet) Marshal() (dAtA []byte, err error) { @@ -2208,6 +2210,11 @@ func (m *DeploymentStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.TerminatingReplicas != nil { + i = encodeVarintGenerated(dAtA, i, uint64(*m.TerminatingReplicas)) + i-- + dAtA[i] = 0x48 + } if m.CollisionCount != nil { i = encodeVarintGenerated(dAtA, i, uint64(*m.CollisionCount)) i-- @@ -3486,6 +3493,11 @@ func (m *ReplicaSetStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.TerminatingReplicas != nil { + i = encodeVarintGenerated(dAtA, i, uint64(*m.TerminatingReplicas)) + i-- + dAtA[i] = 0x38 + } if len(m.Conditions) > 0 { for iNdEx := len(m.Conditions) - 1; iNdEx >= 0; iNdEx-- { { @@ -4024,6 +4036,9 @@ func (m *DeploymentStatus) Size() (n int) { if m.CollisionCount != nil { n += 1 + sovGenerated(uint64(*m.CollisionCount)) } + if m.TerminatingReplicas != nil { + n += 1 + sovGenerated(uint64(*m.TerminatingReplicas)) + } return n } @@ -4502,6 +4517,9 @@ func (m *ReplicaSetStatus) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) } } + if m.TerminatingReplicas != nil { + n += 1 + sovGenerated(uint64(*m.TerminatingReplicas)) + } return n } @@ -4793,6 +4811,7 @@ func (this *DeploymentStatus) String() string { `Conditions:` + repeatedStringForConditions + `,`, `ReadyReplicas:` + fmt.Sprintf("%v", this.ReadyReplicas) + `,`, `CollisionCount:` + valueToStringGenerated(this.CollisionCount) + `,`, + `TerminatingReplicas:` + valueToStringGenerated(this.TerminatingReplicas) + `,`, `}`, }, "") return s @@ -5182,6 +5201,7 @@ func (this *ReplicaSetStatus) String() string { `ReadyReplicas:` + fmt.Sprintf("%v", this.ReadyReplicas) + `,`, `AvailableReplicas:` + fmt.Sprintf("%v", this.AvailableReplicas) + `,`, `Conditions:` + repeatedStringForConditions + `,`, + `TerminatingReplicas:` + valueToStringGenerated(this.TerminatingReplicas) + `,`, `}`, }, "") return s @@ -7567,6 +7587,26 @@ func (m *DeploymentStatus) Unmarshal(dAtA []byte) error { } } m.CollisionCount = &v + case 9: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TerminatingReplicas", wireType) + } + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.TerminatingReplicas = &v default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -11162,6 +11202,26 @@ func (m *ReplicaSetStatus) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TerminatingReplicas", wireType) + } + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.TerminatingReplicas = &v default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/go-controller/vendor/k8s.io/api/extensions/v1beta1/generated.proto b/go-controller/vendor/k8s.io/api/extensions/v1beta1/generated.proto index 9bbcaa0e26..70fcec0cc5 100644 --- a/go-controller/vendor/k8s.io/api/extensions/v1beta1/generated.proto +++ b/go-controller/vendor/k8s.io/api/extensions/v1beta1/generated.proto @@ -320,19 +320,19 @@ message DeploymentStatus { // +optional optional int64 observedGeneration = 1; - // Total number of non-terminated pods targeted by this deployment (their labels match the selector). + // Total number of non-terminating pods targeted by this deployment (their labels match the selector). // +optional optional int32 replicas = 2; - // Total number of non-terminated pods targeted by this deployment that have the desired template spec. + // Total number of non-terminating pods targeted by this deployment that have the desired template spec. // +optional optional int32 updatedReplicas = 3; - // Total number of ready pods targeted by this deployment. + // Total number of non-terminating pods targeted by this Deployment with a Ready Condition. // +optional optional int32 readyReplicas = 7; - // Total number of available pods (ready for at least minReadySeconds) targeted by this deployment. + // Total number of available non-terminating pods (ready for at least minReadySeconds) targeted by this deployment. // +optional optional int32 availableReplicas = 4; @@ -342,6 +342,13 @@ message DeploymentStatus { // +optional optional int32 unavailableReplicas = 5; + // Total number of terminating pods targeted by this deployment. Terminating pods have a non-null + // .metadata.deletionTimestamp and have not yet reached the Failed or Succeeded .status.phase. + // + // This is an alpha field. Enable DeploymentReplicaSetTerminatingReplicas to be able to use this field. + // +optional + optional int32 terminatingReplicas = 9; + // Represents the latest available observations of a deployment's current state. // +patchMergeKey=type // +patchStrategy=merge @@ -863,16 +870,16 @@ message ReplicaSetList { optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; // List of ReplicaSets. - // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller + // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset repeated ReplicaSet items = 2; } // ReplicaSetSpec is the specification of a ReplicaSet. message ReplicaSetSpec { - // Replicas is the number of desired replicas. + // Replicas is the number of desired pods. // This is a pointer to distinguish between explicit zero and unspecified. // Defaults to 1. - // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller + // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset // +optional optional int32 replicas = 1; @@ -891,29 +898,36 @@ message ReplicaSetSpec { // Template is the object that describes the pod that will be created if // insufficient replicas are detected. - // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template + // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/#pod-template // +optional optional .k8s.io.api.core.v1.PodTemplateSpec template = 3; } // ReplicaSetStatus represents the current status of a ReplicaSet. message ReplicaSetStatus { - // Replicas is the most recently observed number of replicas. - // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller + // Replicas is the most recently observed number of non-terminating pods. + // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset optional int32 replicas = 1; - // The number of pods that have labels matching the labels of the pod template of the replicaset. + // The number of non-terminating pods that have labels matching the labels of the pod template of the replicaset. // +optional optional int32 fullyLabeledReplicas = 2; - // The number of ready replicas for this replica set. + // The number of non-terminating pods targeted by this ReplicaSet with a Ready Condition. // +optional optional int32 readyReplicas = 4; - // The number of available replicas (ready for at least minReadySeconds) for this replica set. + // The number of available non-terminating pods (ready for at least minReadySeconds) for this replica set. // +optional optional int32 availableReplicas = 5; + // The number of terminating pods for this replica set. Terminating pods have a non-null .metadata.deletionTimestamp + // and have not yet reached the Failed or Succeeded .status.phase. + // + // This is an alpha field. Enable DeploymentReplicaSetTerminatingReplicas to be able to use this field. + // +optional + optional int32 terminatingReplicas = 7; + // ObservedGeneration reflects the generation of the most recently observed ReplicaSet. // +optional optional int64 observedGeneration = 3; diff --git a/go-controller/vendor/k8s.io/api/extensions/v1beta1/types.go b/go-controller/vendor/k8s.io/api/extensions/v1beta1/types.go index 09f58692f4..b80a7a7e16 100644 --- a/go-controller/vendor/k8s.io/api/extensions/v1beta1/types.go +++ b/go-controller/vendor/k8s.io/api/extensions/v1beta1/types.go @@ -245,19 +245,19 @@ type DeploymentStatus struct { // +optional ObservedGeneration int64 `json:"observedGeneration,omitempty" protobuf:"varint,1,opt,name=observedGeneration"` - // Total number of non-terminated pods targeted by this deployment (their labels match the selector). + // Total number of non-terminating pods targeted by this deployment (their labels match the selector). // +optional Replicas int32 `json:"replicas,omitempty" protobuf:"varint,2,opt,name=replicas"` - // Total number of non-terminated pods targeted by this deployment that have the desired template spec. + // Total number of non-terminating pods targeted by this deployment that have the desired template spec. // +optional UpdatedReplicas int32 `json:"updatedReplicas,omitempty" protobuf:"varint,3,opt,name=updatedReplicas"` - // Total number of ready pods targeted by this deployment. + // Total number of non-terminating pods targeted by this Deployment with a Ready Condition. // +optional ReadyReplicas int32 `json:"readyReplicas,omitempty" protobuf:"varint,7,opt,name=readyReplicas"` - // Total number of available pods (ready for at least minReadySeconds) targeted by this deployment. + // Total number of available non-terminating pods (ready for at least minReadySeconds) targeted by this deployment. // +optional AvailableReplicas int32 `json:"availableReplicas,omitempty" protobuf:"varint,4,opt,name=availableReplicas"` @@ -267,6 +267,13 @@ type DeploymentStatus struct { // +optional UnavailableReplicas int32 `json:"unavailableReplicas,omitempty" protobuf:"varint,5,opt,name=unavailableReplicas"` + // Total number of terminating pods targeted by this deployment. Terminating pods have a non-null + // .metadata.deletionTimestamp and have not yet reached the Failed or Succeeded .status.phase. + // + // This is an alpha field. Enable DeploymentReplicaSetTerminatingReplicas to be able to use this field. + // +optional + TerminatingReplicas *int32 `json:"terminatingReplicas,omitempty" protobuf:"varint,9,opt,name=terminatingReplicas"` + // Represents the latest available observations of a deployment's current state. // +patchMergeKey=type // +patchStrategy=merge @@ -941,16 +948,16 @@ type ReplicaSetList struct { metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` // List of ReplicaSets. - // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller + // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset Items []ReplicaSet `json:"items" protobuf:"bytes,2,rep,name=items"` } // ReplicaSetSpec is the specification of a ReplicaSet. type ReplicaSetSpec struct { - // Replicas is the number of desired replicas. + // Replicas is the number of desired pods. // This is a pointer to distinguish between explicit zero and unspecified. // Defaults to 1. - // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller + // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset // +optional Replicas *int32 `json:"replicas,omitempty" protobuf:"varint,1,opt,name=replicas"` @@ -969,29 +976,36 @@ type ReplicaSetSpec struct { // Template is the object that describes the pod that will be created if // insufficient replicas are detected. - // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template + // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/#pod-template // +optional Template v1.PodTemplateSpec `json:"template,omitempty" protobuf:"bytes,3,opt,name=template"` } // ReplicaSetStatus represents the current status of a ReplicaSet. type ReplicaSetStatus struct { - // Replicas is the most recently observed number of replicas. - // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller + // Replicas is the most recently observed number of non-terminating pods. + // More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset Replicas int32 `json:"replicas" protobuf:"varint,1,opt,name=replicas"` - // The number of pods that have labels matching the labels of the pod template of the replicaset. + // The number of non-terminating pods that have labels matching the labels of the pod template of the replicaset. // +optional FullyLabeledReplicas int32 `json:"fullyLabeledReplicas,omitempty" protobuf:"varint,2,opt,name=fullyLabeledReplicas"` - // The number of ready replicas for this replica set. + // The number of non-terminating pods targeted by this ReplicaSet with a Ready Condition. // +optional ReadyReplicas int32 `json:"readyReplicas,omitempty" protobuf:"varint,4,opt,name=readyReplicas"` - // The number of available replicas (ready for at least minReadySeconds) for this replica set. + // The number of available non-terminating pods (ready for at least minReadySeconds) for this replica set. // +optional AvailableReplicas int32 `json:"availableReplicas,omitempty" protobuf:"varint,5,opt,name=availableReplicas"` + // The number of terminating pods for this replica set. Terminating pods have a non-null .metadata.deletionTimestamp + // and have not yet reached the Failed or Succeeded .status.phase. + // + // This is an alpha field. Enable DeploymentReplicaSetTerminatingReplicas to be able to use this field. + // +optional + TerminatingReplicas *int32 `json:"terminatingReplicas,omitempty" protobuf:"varint,7,opt,name=terminatingReplicas"` + // ObservedGeneration reflects the generation of the most recently observed ReplicaSet. // +optional ObservedGeneration int64 `json:"observedGeneration,omitempty" protobuf:"varint,3,opt,name=observedGeneration"` diff --git a/go-controller/vendor/k8s.io/api/extensions/v1beta1/types_swagger_doc_generated.go b/go-controller/vendor/k8s.io/api/extensions/v1beta1/types_swagger_doc_generated.go index 408022c9d8..923fab3aa1 100644 --- a/go-controller/vendor/k8s.io/api/extensions/v1beta1/types_swagger_doc_generated.go +++ b/go-controller/vendor/k8s.io/api/extensions/v1beta1/types_swagger_doc_generated.go @@ -169,11 +169,12 @@ func (DeploymentSpec) SwaggerDoc() map[string]string { var map_DeploymentStatus = map[string]string{ "": "DeploymentStatus is the most recently observed status of the Deployment.", "observedGeneration": "The generation observed by the deployment controller.", - "replicas": "Total number of non-terminated pods targeted by this deployment (their labels match the selector).", - "updatedReplicas": "Total number of non-terminated pods targeted by this deployment that have the desired template spec.", - "readyReplicas": "Total number of ready pods targeted by this deployment.", - "availableReplicas": "Total number of available pods (ready for at least minReadySeconds) targeted by this deployment.", + "replicas": "Total number of non-terminating pods targeted by this deployment (their labels match the selector).", + "updatedReplicas": "Total number of non-terminating pods targeted by this deployment that have the desired template spec.", + "readyReplicas": "Total number of non-terminating pods targeted by this Deployment with a Ready Condition.", + "availableReplicas": "Total number of available non-terminating pods (ready for at least minReadySeconds) targeted by this deployment.", "unavailableReplicas": "Total number of unavailable pods targeted by this deployment. This is the total number of pods that are still required for the deployment to have 100% available capacity. They may either be pods that are running but not yet available or pods that still have not been created.", + "terminatingReplicas": "Total number of terminating pods targeted by this deployment. Terminating pods have a non-null .metadata.deletionTimestamp and have not yet reached the Failed or Succeeded .status.phase.\n\nThis is an alpha field. Enable DeploymentReplicaSetTerminatingReplicas to be able to use this field.", "conditions": "Represents the latest available observations of a deployment's current state.", "collisionCount": "Count of hash collisions for the Deployment. The Deployment controller uses this field as a collision avoidance mechanism when it needs to create the name for the newest ReplicaSet.", } @@ -435,7 +436,7 @@ func (ReplicaSetCondition) SwaggerDoc() map[string]string { var map_ReplicaSetList = map[string]string{ "": "ReplicaSetList is a collection of ReplicaSets.", "metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - "items": "List of ReplicaSets. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller", + "items": "List of ReplicaSets. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset", } func (ReplicaSetList) SwaggerDoc() map[string]string { @@ -444,10 +445,10 @@ func (ReplicaSetList) SwaggerDoc() map[string]string { var map_ReplicaSetSpec = map[string]string{ "": "ReplicaSetSpec is the specification of a ReplicaSet.", - "replicas": "Replicas is the number of desired replicas. This is a pointer to distinguish between explicit zero and unspecified. Defaults to 1. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller", + "replicas": "Replicas is the number of desired pods. This is a pointer to distinguish between explicit zero and unspecified. Defaults to 1. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset", "minReadySeconds": "Minimum number of seconds for which a newly created pod should be ready without any of its container crashing, for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready)", "selector": "Selector is a label query over pods that should match the replica count. If the selector is empty, it is defaulted to the labels present on the pod template. Label keys and values that must match in order to be controlled by this replica set. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors", - "template": "Template is the object that describes the pod that will be created if insufficient replicas are detected. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template", + "template": "Template is the object that describes the pod that will be created if insufficient replicas are detected. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/#pod-template", } func (ReplicaSetSpec) SwaggerDoc() map[string]string { @@ -456,10 +457,11 @@ func (ReplicaSetSpec) SwaggerDoc() map[string]string { var map_ReplicaSetStatus = map[string]string{ "": "ReplicaSetStatus represents the current status of a ReplicaSet.", - "replicas": "Replicas is the most recently observed number of replicas. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/#what-is-a-replicationcontroller", - "fullyLabeledReplicas": "The number of pods that have labels matching the labels of the pod template of the replicaset.", - "readyReplicas": "The number of ready replicas for this replica set.", - "availableReplicas": "The number of available replicas (ready for at least minReadySeconds) for this replica set.", + "replicas": "Replicas is the most recently observed number of non-terminating pods. More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset", + "fullyLabeledReplicas": "The number of non-terminating pods that have labels matching the labels of the pod template of the replicaset.", + "readyReplicas": "The number of non-terminating pods targeted by this ReplicaSet with a Ready Condition.", + "availableReplicas": "The number of available non-terminating pods (ready for at least minReadySeconds) for this replica set.", + "terminatingReplicas": "The number of terminating pods for this replica set. Terminating pods have a non-null .metadata.deletionTimestamp and have not yet reached the Failed or Succeeded .status.phase.\n\nThis is an alpha field. Enable DeploymentReplicaSetTerminatingReplicas to be able to use this field.", "observedGeneration": "ObservedGeneration reflects the generation of the most recently observed ReplicaSet.", "conditions": "Represents the latest available observations of a replica set's current state.", } diff --git a/go-controller/vendor/k8s.io/api/extensions/v1beta1/zz_generated.deepcopy.go b/go-controller/vendor/k8s.io/api/extensions/v1beta1/zz_generated.deepcopy.go index 6b474ae483..2c7a8524ea 100644 --- a/go-controller/vendor/k8s.io/api/extensions/v1beta1/zz_generated.deepcopy.go +++ b/go-controller/vendor/k8s.io/api/extensions/v1beta1/zz_generated.deepcopy.go @@ -341,6 +341,11 @@ func (in *DeploymentSpec) DeepCopy() *DeploymentSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DeploymentStatus) DeepCopyInto(out *DeploymentStatus) { *out = *in + if in.TerminatingReplicas != nil { + in, out := &in.TerminatingReplicas, &out.TerminatingReplicas + *out = new(int32) + **out = **in + } if in.Conditions != nil { in, out := &in.Conditions, &out.Conditions *out = make([]DeploymentCondition, len(*in)) @@ -1045,6 +1050,11 @@ func (in *ReplicaSetSpec) DeepCopy() *ReplicaSetSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ReplicaSetStatus) DeepCopyInto(out *ReplicaSetStatus) { *out = *in + if in.TerminatingReplicas != nil { + in, out := &in.TerminatingReplicas, &out.TerminatingReplicas + *out = new(int32) + **out = **in + } if in.Conditions != nil { in, out := &in.Conditions, &out.Conditions *out = make([]ReplicaSetCondition, len(*in)) diff --git a/go-controller/vendor/k8s.io/api/flowcontrol/v1/doc.go b/go-controller/vendor/k8s.io/api/flowcontrol/v1/doc.go index c9e7db1589..ad5f457919 100644 --- a/go-controller/vendor/k8s.io/api/flowcontrol/v1/doc.go +++ b/go-controller/vendor/k8s.io/api/flowcontrol/v1/doc.go @@ -22,4 +22,4 @@ limitations under the License. // +groupName=flowcontrol.apiserver.k8s.io // Package v1 holds api types of version v1 for group "flowcontrol.apiserver.k8s.io". -package v1 // import "k8s.io/api/flowcontrol/v1" +package v1 diff --git a/go-controller/vendor/k8s.io/api/flowcontrol/v1beta1/doc.go b/go-controller/vendor/k8s.io/api/flowcontrol/v1beta1/doc.go index 50897b7eb5..20268c1f2d 100644 --- a/go-controller/vendor/k8s.io/api/flowcontrol/v1beta1/doc.go +++ b/go-controller/vendor/k8s.io/api/flowcontrol/v1beta1/doc.go @@ -22,4 +22,4 @@ limitations under the License. // +groupName=flowcontrol.apiserver.k8s.io // Package v1beta1 holds api types of version v1alpha1 for group "flowcontrol.apiserver.k8s.io". -package v1beta1 // import "k8s.io/api/flowcontrol/v1beta1" +package v1beta1 diff --git a/go-controller/vendor/k8s.io/api/flowcontrol/v1beta2/doc.go b/go-controller/vendor/k8s.io/api/flowcontrol/v1beta2/doc.go index 53b460d374..2dcad11ad9 100644 --- a/go-controller/vendor/k8s.io/api/flowcontrol/v1beta2/doc.go +++ b/go-controller/vendor/k8s.io/api/flowcontrol/v1beta2/doc.go @@ -22,4 +22,4 @@ limitations under the License. // +groupName=flowcontrol.apiserver.k8s.io // Package v1beta2 holds api types of version v1alpha1 for group "flowcontrol.apiserver.k8s.io". -package v1beta2 // import "k8s.io/api/flowcontrol/v1beta2" +package v1beta2 diff --git a/go-controller/vendor/k8s.io/api/flowcontrol/v1beta3/doc.go b/go-controller/vendor/k8s.io/api/flowcontrol/v1beta3/doc.go index cd60cfef7f..95f4430d38 100644 --- a/go-controller/vendor/k8s.io/api/flowcontrol/v1beta3/doc.go +++ b/go-controller/vendor/k8s.io/api/flowcontrol/v1beta3/doc.go @@ -22,4 +22,4 @@ limitations under the License. // +groupName=flowcontrol.apiserver.k8s.io // Package v1beta3 holds api types of version v1beta3 for group "flowcontrol.apiserver.k8s.io". -package v1beta3 // import "k8s.io/api/flowcontrol/v1beta3" +package v1beta3 diff --git a/go-controller/vendor/k8s.io/api/imagepolicy/v1alpha1/doc.go b/go-controller/vendor/k8s.io/api/imagepolicy/v1alpha1/doc.go index 5db6d52d47..f5fbbdbf0c 100644 --- a/go-controller/vendor/k8s.io/api/imagepolicy/v1alpha1/doc.go +++ b/go-controller/vendor/k8s.io/api/imagepolicy/v1alpha1/doc.go @@ -20,4 +20,4 @@ limitations under the License. // +groupName=imagepolicy.k8s.io -package v1alpha1 // import "k8s.io/api/imagepolicy/v1alpha1" +package v1alpha1 diff --git a/go-controller/vendor/k8s.io/api/networking/v1/doc.go b/go-controller/vendor/k8s.io/api/networking/v1/doc.go index 1d13e7bab3..e2093b7df6 100644 --- a/go-controller/vendor/k8s.io/api/networking/v1/doc.go +++ b/go-controller/vendor/k8s.io/api/networking/v1/doc.go @@ -20,4 +20,4 @@ limitations under the License. // +k8s:prerelease-lifecycle-gen=true // +groupName=networking.k8s.io -package v1 // import "k8s.io/api/networking/v1" +package v1 diff --git a/go-controller/vendor/k8s.io/api/networking/v1/generated.pb.go b/go-controller/vendor/k8s.io/api/networking/v1/generated.pb.go index 7c023e6903..062382b633 100644 --- a/go-controller/vendor/k8s.io/api/networking/v1/generated.pb.go +++ b/go-controller/vendor/k8s.io/api/networking/v1/generated.pb.go @@ -104,10 +104,94 @@ func (m *HTTPIngressRuleValue) XXX_DiscardUnknown() { var xxx_messageInfo_HTTPIngressRuleValue proto.InternalMessageInfo +func (m *IPAddress) Reset() { *m = IPAddress{} } +func (*IPAddress) ProtoMessage() {} +func (*IPAddress) Descriptor() ([]byte, []int) { + return fileDescriptor_2c41434372fec1d7, []int{2} +} +func (m *IPAddress) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *IPAddress) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *IPAddress) XXX_Merge(src proto.Message) { + xxx_messageInfo_IPAddress.Merge(m, src) +} +func (m *IPAddress) XXX_Size() int { + return m.Size() +} +func (m *IPAddress) XXX_DiscardUnknown() { + xxx_messageInfo_IPAddress.DiscardUnknown(m) +} + +var xxx_messageInfo_IPAddress proto.InternalMessageInfo + +func (m *IPAddressList) Reset() { *m = IPAddressList{} } +func (*IPAddressList) ProtoMessage() {} +func (*IPAddressList) Descriptor() ([]byte, []int) { + return fileDescriptor_2c41434372fec1d7, []int{3} +} +func (m *IPAddressList) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *IPAddressList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *IPAddressList) XXX_Merge(src proto.Message) { + xxx_messageInfo_IPAddressList.Merge(m, src) +} +func (m *IPAddressList) XXX_Size() int { + return m.Size() +} +func (m *IPAddressList) XXX_DiscardUnknown() { + xxx_messageInfo_IPAddressList.DiscardUnknown(m) +} + +var xxx_messageInfo_IPAddressList proto.InternalMessageInfo + +func (m *IPAddressSpec) Reset() { *m = IPAddressSpec{} } +func (*IPAddressSpec) ProtoMessage() {} +func (*IPAddressSpec) Descriptor() ([]byte, []int) { + return fileDescriptor_2c41434372fec1d7, []int{4} +} +func (m *IPAddressSpec) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *IPAddressSpec) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *IPAddressSpec) XXX_Merge(src proto.Message) { + xxx_messageInfo_IPAddressSpec.Merge(m, src) +} +func (m *IPAddressSpec) XXX_Size() int { + return m.Size() +} +func (m *IPAddressSpec) XXX_DiscardUnknown() { + xxx_messageInfo_IPAddressSpec.DiscardUnknown(m) +} + +var xxx_messageInfo_IPAddressSpec proto.InternalMessageInfo + func (m *IPBlock) Reset() { *m = IPBlock{} } func (*IPBlock) ProtoMessage() {} func (*IPBlock) Descriptor() ([]byte, []int) { - return fileDescriptor_2c41434372fec1d7, []int{2} + return fileDescriptor_2c41434372fec1d7, []int{5} } func (m *IPBlock) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -135,7 +219,7 @@ var xxx_messageInfo_IPBlock proto.InternalMessageInfo func (m *Ingress) Reset() { *m = Ingress{} } func (*Ingress) ProtoMessage() {} func (*Ingress) Descriptor() ([]byte, []int) { - return fileDescriptor_2c41434372fec1d7, []int{3} + return fileDescriptor_2c41434372fec1d7, []int{6} } func (m *Ingress) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -163,7 +247,7 @@ var xxx_messageInfo_Ingress proto.InternalMessageInfo func (m *IngressBackend) Reset() { *m = IngressBackend{} } func (*IngressBackend) ProtoMessage() {} func (*IngressBackend) Descriptor() ([]byte, []int) { - return fileDescriptor_2c41434372fec1d7, []int{4} + return fileDescriptor_2c41434372fec1d7, []int{7} } func (m *IngressBackend) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -191,7 +275,7 @@ var xxx_messageInfo_IngressBackend proto.InternalMessageInfo func (m *IngressClass) Reset() { *m = IngressClass{} } func (*IngressClass) ProtoMessage() {} func (*IngressClass) Descriptor() ([]byte, []int) { - return fileDescriptor_2c41434372fec1d7, []int{5} + return fileDescriptor_2c41434372fec1d7, []int{8} } func (m *IngressClass) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -219,7 +303,7 @@ var xxx_messageInfo_IngressClass proto.InternalMessageInfo func (m *IngressClassList) Reset() { *m = IngressClassList{} } func (*IngressClassList) ProtoMessage() {} func (*IngressClassList) Descriptor() ([]byte, []int) { - return fileDescriptor_2c41434372fec1d7, []int{6} + return fileDescriptor_2c41434372fec1d7, []int{9} } func (m *IngressClassList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -247,7 +331,7 @@ var xxx_messageInfo_IngressClassList proto.InternalMessageInfo func (m *IngressClassParametersReference) Reset() { *m = IngressClassParametersReference{} } func (*IngressClassParametersReference) ProtoMessage() {} func (*IngressClassParametersReference) Descriptor() ([]byte, []int) { - return fileDescriptor_2c41434372fec1d7, []int{7} + return fileDescriptor_2c41434372fec1d7, []int{10} } func (m *IngressClassParametersReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -275,7 +359,7 @@ var xxx_messageInfo_IngressClassParametersReference proto.InternalMessageInfo func (m *IngressClassSpec) Reset() { *m = IngressClassSpec{} } func (*IngressClassSpec) ProtoMessage() {} func (*IngressClassSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_2c41434372fec1d7, []int{8} + return fileDescriptor_2c41434372fec1d7, []int{11} } func (m *IngressClassSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -303,7 +387,7 @@ var xxx_messageInfo_IngressClassSpec proto.InternalMessageInfo func (m *IngressList) Reset() { *m = IngressList{} } func (*IngressList) ProtoMessage() {} func (*IngressList) Descriptor() ([]byte, []int) { - return fileDescriptor_2c41434372fec1d7, []int{9} + return fileDescriptor_2c41434372fec1d7, []int{12} } func (m *IngressList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -331,7 +415,7 @@ var xxx_messageInfo_IngressList proto.InternalMessageInfo func (m *IngressLoadBalancerIngress) Reset() { *m = IngressLoadBalancerIngress{} } func (*IngressLoadBalancerIngress) ProtoMessage() {} func (*IngressLoadBalancerIngress) Descriptor() ([]byte, []int) { - return fileDescriptor_2c41434372fec1d7, []int{10} + return fileDescriptor_2c41434372fec1d7, []int{13} } func (m *IngressLoadBalancerIngress) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -359,7 +443,7 @@ var xxx_messageInfo_IngressLoadBalancerIngress proto.InternalMessageInfo func (m *IngressLoadBalancerStatus) Reset() { *m = IngressLoadBalancerStatus{} } func (*IngressLoadBalancerStatus) ProtoMessage() {} func (*IngressLoadBalancerStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_2c41434372fec1d7, []int{11} + return fileDescriptor_2c41434372fec1d7, []int{14} } func (m *IngressLoadBalancerStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -387,7 +471,7 @@ var xxx_messageInfo_IngressLoadBalancerStatus proto.InternalMessageInfo func (m *IngressPortStatus) Reset() { *m = IngressPortStatus{} } func (*IngressPortStatus) ProtoMessage() {} func (*IngressPortStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_2c41434372fec1d7, []int{12} + return fileDescriptor_2c41434372fec1d7, []int{15} } func (m *IngressPortStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -415,7 +499,7 @@ var xxx_messageInfo_IngressPortStatus proto.InternalMessageInfo func (m *IngressRule) Reset() { *m = IngressRule{} } func (*IngressRule) ProtoMessage() {} func (*IngressRule) Descriptor() ([]byte, []int) { - return fileDescriptor_2c41434372fec1d7, []int{13} + return fileDescriptor_2c41434372fec1d7, []int{16} } func (m *IngressRule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -443,7 +527,7 @@ var xxx_messageInfo_IngressRule proto.InternalMessageInfo func (m *IngressRuleValue) Reset() { *m = IngressRuleValue{} } func (*IngressRuleValue) ProtoMessage() {} func (*IngressRuleValue) Descriptor() ([]byte, []int) { - return fileDescriptor_2c41434372fec1d7, []int{14} + return fileDescriptor_2c41434372fec1d7, []int{17} } func (m *IngressRuleValue) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -471,7 +555,7 @@ var xxx_messageInfo_IngressRuleValue proto.InternalMessageInfo func (m *IngressServiceBackend) Reset() { *m = IngressServiceBackend{} } func (*IngressServiceBackend) ProtoMessage() {} func (*IngressServiceBackend) Descriptor() ([]byte, []int) { - return fileDescriptor_2c41434372fec1d7, []int{15} + return fileDescriptor_2c41434372fec1d7, []int{18} } func (m *IngressServiceBackend) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -499,7 +583,7 @@ var xxx_messageInfo_IngressServiceBackend proto.InternalMessageInfo func (m *IngressSpec) Reset() { *m = IngressSpec{} } func (*IngressSpec) ProtoMessage() {} func (*IngressSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_2c41434372fec1d7, []int{16} + return fileDescriptor_2c41434372fec1d7, []int{19} } func (m *IngressSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -527,7 +611,7 @@ var xxx_messageInfo_IngressSpec proto.InternalMessageInfo func (m *IngressStatus) Reset() { *m = IngressStatus{} } func (*IngressStatus) ProtoMessage() {} func (*IngressStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_2c41434372fec1d7, []int{17} + return fileDescriptor_2c41434372fec1d7, []int{20} } func (m *IngressStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -555,7 +639,7 @@ var xxx_messageInfo_IngressStatus proto.InternalMessageInfo func (m *IngressTLS) Reset() { *m = IngressTLS{} } func (*IngressTLS) ProtoMessage() {} func (*IngressTLS) Descriptor() ([]byte, []int) { - return fileDescriptor_2c41434372fec1d7, []int{18} + return fileDescriptor_2c41434372fec1d7, []int{21} } func (m *IngressTLS) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -583,7 +667,7 @@ var xxx_messageInfo_IngressTLS proto.InternalMessageInfo func (m *NetworkPolicy) Reset() { *m = NetworkPolicy{} } func (*NetworkPolicy) ProtoMessage() {} func (*NetworkPolicy) Descriptor() ([]byte, []int) { - return fileDescriptor_2c41434372fec1d7, []int{19} + return fileDescriptor_2c41434372fec1d7, []int{22} } func (m *NetworkPolicy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -611,7 +695,7 @@ var xxx_messageInfo_NetworkPolicy proto.InternalMessageInfo func (m *NetworkPolicyEgressRule) Reset() { *m = NetworkPolicyEgressRule{} } func (*NetworkPolicyEgressRule) ProtoMessage() {} func (*NetworkPolicyEgressRule) Descriptor() ([]byte, []int) { - return fileDescriptor_2c41434372fec1d7, []int{20} + return fileDescriptor_2c41434372fec1d7, []int{23} } func (m *NetworkPolicyEgressRule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -639,7 +723,7 @@ var xxx_messageInfo_NetworkPolicyEgressRule proto.InternalMessageInfo func (m *NetworkPolicyIngressRule) Reset() { *m = NetworkPolicyIngressRule{} } func (*NetworkPolicyIngressRule) ProtoMessage() {} func (*NetworkPolicyIngressRule) Descriptor() ([]byte, []int) { - return fileDescriptor_2c41434372fec1d7, []int{21} + return fileDescriptor_2c41434372fec1d7, []int{24} } func (m *NetworkPolicyIngressRule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -667,7 +751,7 @@ var xxx_messageInfo_NetworkPolicyIngressRule proto.InternalMessageInfo func (m *NetworkPolicyList) Reset() { *m = NetworkPolicyList{} } func (*NetworkPolicyList) ProtoMessage() {} func (*NetworkPolicyList) Descriptor() ([]byte, []int) { - return fileDescriptor_2c41434372fec1d7, []int{22} + return fileDescriptor_2c41434372fec1d7, []int{25} } func (m *NetworkPolicyList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -695,7 +779,7 @@ var xxx_messageInfo_NetworkPolicyList proto.InternalMessageInfo func (m *NetworkPolicyPeer) Reset() { *m = NetworkPolicyPeer{} } func (*NetworkPolicyPeer) ProtoMessage() {} func (*NetworkPolicyPeer) Descriptor() ([]byte, []int) { - return fileDescriptor_2c41434372fec1d7, []int{23} + return fileDescriptor_2c41434372fec1d7, []int{26} } func (m *NetworkPolicyPeer) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -723,7 +807,7 @@ var xxx_messageInfo_NetworkPolicyPeer proto.InternalMessageInfo func (m *NetworkPolicyPort) Reset() { *m = NetworkPolicyPort{} } func (*NetworkPolicyPort) ProtoMessage() {} func (*NetworkPolicyPort) Descriptor() ([]byte, []int) { - return fileDescriptor_2c41434372fec1d7, []int{24} + return fileDescriptor_2c41434372fec1d7, []int{27} } func (m *NetworkPolicyPort) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -751,7 +835,7 @@ var xxx_messageInfo_NetworkPolicyPort proto.InternalMessageInfo func (m *NetworkPolicySpec) Reset() { *m = NetworkPolicySpec{} } func (*NetworkPolicySpec) ProtoMessage() {} func (*NetworkPolicySpec) Descriptor() ([]byte, []int) { - return fileDescriptor_2c41434372fec1d7, []int{25} + return fileDescriptor_2c41434372fec1d7, []int{28} } func (m *NetworkPolicySpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -776,10 +860,38 @@ func (m *NetworkPolicySpec) XXX_DiscardUnknown() { var xxx_messageInfo_NetworkPolicySpec proto.InternalMessageInfo +func (m *ParentReference) Reset() { *m = ParentReference{} } +func (*ParentReference) ProtoMessage() {} +func (*ParentReference) Descriptor() ([]byte, []int) { + return fileDescriptor_2c41434372fec1d7, []int{29} +} +func (m *ParentReference) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ParentReference) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ParentReference) XXX_Merge(src proto.Message) { + xxx_messageInfo_ParentReference.Merge(m, src) +} +func (m *ParentReference) XXX_Size() int { + return m.Size() +} +func (m *ParentReference) XXX_DiscardUnknown() { + xxx_messageInfo_ParentReference.DiscardUnknown(m) +} + +var xxx_messageInfo_ParentReference proto.InternalMessageInfo + func (m *ServiceBackendPort) Reset() { *m = ServiceBackendPort{} } func (*ServiceBackendPort) ProtoMessage() {} func (*ServiceBackendPort) Descriptor() ([]byte, []int) { - return fileDescriptor_2c41434372fec1d7, []int{26} + return fileDescriptor_2c41434372fec1d7, []int{30} } func (m *ServiceBackendPort) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -804,9 +916,124 @@ func (m *ServiceBackendPort) XXX_DiscardUnknown() { var xxx_messageInfo_ServiceBackendPort proto.InternalMessageInfo +func (m *ServiceCIDR) Reset() { *m = ServiceCIDR{} } +func (*ServiceCIDR) ProtoMessage() {} +func (*ServiceCIDR) Descriptor() ([]byte, []int) { + return fileDescriptor_2c41434372fec1d7, []int{31} +} +func (m *ServiceCIDR) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ServiceCIDR) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ServiceCIDR) XXX_Merge(src proto.Message) { + xxx_messageInfo_ServiceCIDR.Merge(m, src) +} +func (m *ServiceCIDR) XXX_Size() int { + return m.Size() +} +func (m *ServiceCIDR) XXX_DiscardUnknown() { + xxx_messageInfo_ServiceCIDR.DiscardUnknown(m) +} + +var xxx_messageInfo_ServiceCIDR proto.InternalMessageInfo + +func (m *ServiceCIDRList) Reset() { *m = ServiceCIDRList{} } +func (*ServiceCIDRList) ProtoMessage() {} +func (*ServiceCIDRList) Descriptor() ([]byte, []int) { + return fileDescriptor_2c41434372fec1d7, []int{32} +} +func (m *ServiceCIDRList) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ServiceCIDRList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ServiceCIDRList) XXX_Merge(src proto.Message) { + xxx_messageInfo_ServiceCIDRList.Merge(m, src) +} +func (m *ServiceCIDRList) XXX_Size() int { + return m.Size() +} +func (m *ServiceCIDRList) XXX_DiscardUnknown() { + xxx_messageInfo_ServiceCIDRList.DiscardUnknown(m) +} + +var xxx_messageInfo_ServiceCIDRList proto.InternalMessageInfo + +func (m *ServiceCIDRSpec) Reset() { *m = ServiceCIDRSpec{} } +func (*ServiceCIDRSpec) ProtoMessage() {} +func (*ServiceCIDRSpec) Descriptor() ([]byte, []int) { + return fileDescriptor_2c41434372fec1d7, []int{33} +} +func (m *ServiceCIDRSpec) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ServiceCIDRSpec) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ServiceCIDRSpec) XXX_Merge(src proto.Message) { + xxx_messageInfo_ServiceCIDRSpec.Merge(m, src) +} +func (m *ServiceCIDRSpec) XXX_Size() int { + return m.Size() +} +func (m *ServiceCIDRSpec) XXX_DiscardUnknown() { + xxx_messageInfo_ServiceCIDRSpec.DiscardUnknown(m) +} + +var xxx_messageInfo_ServiceCIDRSpec proto.InternalMessageInfo + +func (m *ServiceCIDRStatus) Reset() { *m = ServiceCIDRStatus{} } +func (*ServiceCIDRStatus) ProtoMessage() {} +func (*ServiceCIDRStatus) Descriptor() ([]byte, []int) { + return fileDescriptor_2c41434372fec1d7, []int{34} +} +func (m *ServiceCIDRStatus) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ServiceCIDRStatus) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *ServiceCIDRStatus) XXX_Merge(src proto.Message) { + xxx_messageInfo_ServiceCIDRStatus.Merge(m, src) +} +func (m *ServiceCIDRStatus) XXX_Size() int { + return m.Size() +} +func (m *ServiceCIDRStatus) XXX_DiscardUnknown() { + xxx_messageInfo_ServiceCIDRStatus.DiscardUnknown(m) +} + +var xxx_messageInfo_ServiceCIDRStatus proto.InternalMessageInfo + func init() { proto.RegisterType((*HTTPIngressPath)(nil), "k8s.io.api.networking.v1.HTTPIngressPath") proto.RegisterType((*HTTPIngressRuleValue)(nil), "k8s.io.api.networking.v1.HTTPIngressRuleValue") + proto.RegisterType((*IPAddress)(nil), "k8s.io.api.networking.v1.IPAddress") + proto.RegisterType((*IPAddressList)(nil), "k8s.io.api.networking.v1.IPAddressList") + proto.RegisterType((*IPAddressSpec)(nil), "k8s.io.api.networking.v1.IPAddressSpec") proto.RegisterType((*IPBlock)(nil), "k8s.io.api.networking.v1.IPBlock") proto.RegisterType((*Ingress)(nil), "k8s.io.api.networking.v1.Ingress") proto.RegisterType((*IngressBackend)(nil), "k8s.io.api.networking.v1.IngressBackend") @@ -831,7 +1058,12 @@ func init() { proto.RegisterType((*NetworkPolicyPeer)(nil), "k8s.io.api.networking.v1.NetworkPolicyPeer") proto.RegisterType((*NetworkPolicyPort)(nil), "k8s.io.api.networking.v1.NetworkPolicyPort") proto.RegisterType((*NetworkPolicySpec)(nil), "k8s.io.api.networking.v1.NetworkPolicySpec") + proto.RegisterType((*ParentReference)(nil), "k8s.io.api.networking.v1.ParentReference") proto.RegisterType((*ServiceBackendPort)(nil), "k8s.io.api.networking.v1.ServiceBackendPort") + proto.RegisterType((*ServiceCIDR)(nil), "k8s.io.api.networking.v1.ServiceCIDR") + proto.RegisterType((*ServiceCIDRList)(nil), "k8s.io.api.networking.v1.ServiceCIDRList") + proto.RegisterType((*ServiceCIDRSpec)(nil), "k8s.io.api.networking.v1.ServiceCIDRSpec") + proto.RegisterType((*ServiceCIDRStatus)(nil), "k8s.io.api.networking.v1.ServiceCIDRStatus") } func init() { @@ -839,111 +1071,125 @@ func init() { } var fileDescriptor_2c41434372fec1d7 = []byte{ - // 1652 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0x4b, 0x6f, 0x1b, 0x55, - 0x14, 0xce, 0x38, 0x71, 0xec, 0x1c, 0x27, 0x69, 0x72, 0x69, 0x85, 0x09, 0xc2, 0x0e, 0x23, 0xda, - 0x06, 0xda, 0xda, 0x34, 0xad, 0x10, 0x6c, 0x78, 0x4c, 0x9a, 0xa6, 0xa1, 0xa9, 0x63, 0x5d, 0x5b, - 0x45, 0x20, 0x1e, 0x9d, 0x8c, 0x6f, 0x9c, 0x69, 0xc6, 0x33, 0xa3, 0x3b, 0xd7, 0xa5, 0x95, 0x10, - 0x62, 0xc3, 0x82, 0x1d, 0x7f, 0x01, 0xf1, 0x0b, 0x10, 0x2c, 0x90, 0x10, 0x14, 0x36, 0xa8, 0xcb, - 0x4a, 0x6c, 0xba, 0xc1, 0xa2, 0xe6, 0x5f, 0x64, 0x85, 0xee, 0x63, 0x1e, 0x7e, 0xd5, 0xa6, 0xaa, - 0xb2, 0x4a, 0xee, 0x39, 0xe7, 0x7e, 0xe7, 0x71, 0xcf, 0x6b, 0x0c, 0x6b, 0x87, 0x6f, 0x06, 0x25, - 0xdb, 0x2b, 0x9b, 0xbe, 0x5d, 0x76, 0x09, 0xfb, 0xdc, 0xa3, 0x87, 0xb6, 0xdb, 0x2c, 0xdf, 0xb9, - 0x58, 0x6e, 0x12, 0x97, 0x50, 0x93, 0x91, 0x46, 0xc9, 0xa7, 0x1e, 0xf3, 0x50, 0x5e, 0x4a, 0x96, - 0x4c, 0xdf, 0x2e, 0xc5, 0x92, 0xa5, 0x3b, 0x17, 0x57, 0x2e, 0x34, 0x6d, 0x76, 0xd0, 0xde, 0x2b, - 0x59, 0x5e, 0xab, 0xdc, 0xf4, 0x9a, 0x5e, 0x59, 0x5c, 0xd8, 0x6b, 0xef, 0x8b, 0x93, 0x38, 0x88, - 0xff, 0x24, 0xd0, 0x8a, 0x9e, 0x50, 0x69, 0x79, 0x94, 0x0c, 0x51, 0xb6, 0x72, 0x39, 0x96, 0x69, - 0x99, 0xd6, 0x81, 0xed, 0x12, 0x7a, 0xaf, 0xec, 0x1f, 0x36, 0x39, 0x21, 0x28, 0xb7, 0x08, 0x33, - 0x87, 0xdd, 0x2a, 0x8f, 0xba, 0x45, 0xdb, 0x2e, 0xb3, 0x5b, 0x64, 0xe0, 0xc2, 0x1b, 0xe3, 0x2e, - 0x04, 0xd6, 0x01, 0x69, 0x99, 0x03, 0xf7, 0x2e, 0x8d, 0xba, 0xd7, 0x66, 0xb6, 0x53, 0xb6, 0x5d, - 0x16, 0x30, 0xda, 0x7f, 0x49, 0xff, 0x4d, 0x83, 0x13, 0xd7, 0xea, 0xf5, 0xea, 0xb6, 0xdb, 0xa4, - 0x24, 0x08, 0xaa, 0x26, 0x3b, 0x40, 0xab, 0x30, 0xe3, 0x9b, 0xec, 0x20, 0xaf, 0xad, 0x6a, 0x6b, - 0x73, 0xc6, 0xfc, 0x83, 0x4e, 0x71, 0xaa, 0xdb, 0x29, 0xce, 0x70, 0x1e, 0x16, 0x1c, 0x74, 0x19, - 0xb2, 0xfc, 0x6f, 0xfd, 0x9e, 0x4f, 0xf2, 0xd3, 0x42, 0x2a, 0xdf, 0xed, 0x14, 0xb3, 0x55, 0x45, - 0x3b, 0x4a, 0xfc, 0x8f, 0x23, 0x49, 0x54, 0x83, 0xcc, 0x9e, 0x69, 0x1d, 0x12, 0xb7, 0x91, 0x4f, - 0xad, 0x6a, 0x6b, 0xb9, 0xf5, 0xb5, 0xd2, 0xa8, 0xe7, 0x2b, 0x29, 0x7b, 0x0c, 0x29, 0x6f, 0x9c, - 0x50, 0x46, 0x64, 0x14, 0x01, 0x87, 0x48, 0xfa, 0x3e, 0x9c, 0x4c, 0xd8, 0x8f, 0xdb, 0x0e, 0xb9, - 0x69, 0x3a, 0x6d, 0x82, 0x2a, 0x90, 0xe6, 0x8a, 0x83, 0xbc, 0xb6, 0x3a, 0xbd, 0x96, 0x5b, 0x7f, - 0x75, 0xb4, 0xaa, 0x3e, 0xf7, 0x8d, 0x05, 0xa5, 0x2b, 0xcd, 0x4f, 0x01, 0x96, 0x30, 0xfa, 0x2e, - 0x64, 0xb6, 0xab, 0x86, 0xe3, 0x59, 0x87, 0x3c, 0x3e, 0x96, 0xdd, 0xa0, 0xfd, 0xf1, 0xd9, 0xd8, - 0xbe, 0x82, 0xb1, 0xe0, 0x20, 0x1d, 0x66, 0xc9, 0x5d, 0x8b, 0xf8, 0x2c, 0x9f, 0x5a, 0x9d, 0x5e, - 0x9b, 0x33, 0xa0, 0xdb, 0x29, 0xce, 0x6e, 0x0a, 0x0a, 0x56, 0x1c, 0xfd, 0xeb, 0x14, 0x64, 0x94, - 0x5a, 0x74, 0x0b, 0xb2, 0x3c, 0x7d, 0x1a, 0x26, 0x33, 0x05, 0x6a, 0x6e, 0xfd, 0xf5, 0x84, 0xbd, - 0xd1, 0x6b, 0x96, 0xfc, 0xc3, 0x26, 0x27, 0x04, 0x25, 0x2e, 0xcd, 0x6d, 0xdf, 0xdd, 0xbb, 0x4d, - 0x2c, 0x76, 0x83, 0x30, 0xd3, 0x40, 0xca, 0x0e, 0x88, 0x69, 0x38, 0x42, 0x45, 0x5b, 0x30, 0x13, - 0xf8, 0xc4, 0x52, 0x81, 0x3f, 0x3d, 0x36, 0xf0, 0x35, 0x9f, 0x58, 0xb1, 0x6b, 0xfc, 0x84, 0x05, - 0x00, 0xda, 0x85, 0xd9, 0x80, 0x99, 0xac, 0x1d, 0x88, 0x87, 0xcf, 0xad, 0x9f, 0x1d, 0x0f, 0x25, - 0xc4, 0x8d, 0x45, 0x05, 0x36, 0x2b, 0xcf, 0x58, 0xc1, 0xe8, 0x7f, 0x68, 0xb0, 0xd8, 0xfb, 0xda, - 0xe8, 0x26, 0x64, 0x02, 0x42, 0xef, 0xd8, 0x16, 0xc9, 0xcf, 0x08, 0x25, 0xe5, 0xf1, 0x4a, 0xa4, - 0x7c, 0x98, 0x2f, 0x39, 0x9e, 0x2b, 0x8a, 0x86, 0x43, 0x30, 0xf4, 0x01, 0x64, 0x29, 0x09, 0xbc, - 0x36, 0xb5, 0x88, 0xb2, 0xfe, 0x42, 0x12, 0x98, 0xd7, 0x3d, 0x87, 0xe4, 0xc9, 0xda, 0xd8, 0xf1, - 0x2c, 0xd3, 0x91, 0xa1, 0xc4, 0x64, 0x9f, 0x50, 0xe2, 0x5a, 0xc4, 0x98, 0xe7, 0x59, 0x8e, 0x15, - 0x04, 0x8e, 0xc0, 0x78, 0x15, 0xcd, 0x2b, 0x43, 0x36, 0x1c, 0xf3, 0x58, 0x1e, 0x74, 0xa7, 0xe7, - 0x41, 0x5f, 0x1b, 0x1b, 0x20, 0x61, 0xd7, 0xa8, 0x57, 0xd5, 0x7f, 0xd5, 0x60, 0x29, 0x29, 0xb8, - 0x63, 0x07, 0x0c, 0x7d, 0x3c, 0xe0, 0x44, 0x69, 0x32, 0x27, 0xf8, 0x6d, 0xe1, 0xc2, 0x92, 0x52, - 0x95, 0x0d, 0x29, 0x09, 0x07, 0xae, 0x43, 0xda, 0x66, 0xa4, 0x15, 0x88, 0x12, 0xc9, 0xad, 0x9f, - 0x99, 0xcc, 0x83, 0xb8, 0x3a, 0xb7, 0xf9, 0x65, 0x2c, 0x31, 0xf4, 0xbf, 0x35, 0x28, 0x26, 0xc5, - 0xaa, 0x26, 0x35, 0x5b, 0x84, 0x11, 0x1a, 0x44, 0x8f, 0x87, 0xd6, 0x20, 0x6b, 0x56, 0xb7, 0xb7, - 0xa8, 0xd7, 0xf6, 0xc3, 0xd2, 0xe5, 0xa6, 0xbd, 0xa7, 0x68, 0x38, 0xe2, 0xf2, 0x02, 0x3f, 0xb4, - 0x55, 0x97, 0x4a, 0x14, 0xf8, 0x75, 0xdb, 0x6d, 0x60, 0xc1, 0xe1, 0x12, 0xae, 0xd9, 0x0a, 0x9b, - 0x5f, 0x24, 0x51, 0x31, 0x5b, 0x04, 0x0b, 0x0e, 0x2a, 0x42, 0x3a, 0xb0, 0x3c, 0x5f, 0x66, 0xf0, - 0x9c, 0x31, 0xc7, 0x4d, 0xae, 0x71, 0x02, 0x96, 0x74, 0x74, 0x0e, 0xe6, 0xb8, 0x60, 0xe0, 0x9b, - 0x16, 0xc9, 0xa7, 0x85, 0xd0, 0x42, 0xb7, 0x53, 0x9c, 0xab, 0x84, 0x44, 0x1c, 0xf3, 0xf5, 0x1f, - 0xfa, 0xde, 0x87, 0x3f, 0x1d, 0x5a, 0x07, 0xb0, 0x3c, 0x97, 0x51, 0xcf, 0x71, 0x48, 0xd8, 0x8d, - 0xa2, 0xa4, 0xd9, 0x88, 0x38, 0x38, 0x21, 0x85, 0x6c, 0x00, 0x3f, 0x8a, 0x8d, 0x4a, 0x9e, 0xb7, - 0x26, 0x0b, 0xfd, 0x90, 0x98, 0x1a, 0x8b, 0x5c, 0x55, 0x82, 0x91, 0x00, 0xd7, 0x7f, 0xd4, 0x20, - 0xa7, 0xee, 0x1f, 0x43, 0x3a, 0x5d, 0xed, 0x4d, 0xa7, 0x97, 0xc7, 0x8f, 0x96, 0xe1, 0x99, 0xf4, - 0xb3, 0x06, 0x2b, 0xa1, 0xd5, 0x9e, 0xd9, 0x30, 0x4c, 0xc7, 0x74, 0x2d, 0x42, 0xc3, 0x4e, 0xbd, - 0x02, 0x29, 0x3b, 0x4c, 0x1f, 0x50, 0x00, 0xa9, 0xed, 0x2a, 0x4e, 0xd9, 0x3e, 0x3a, 0x0f, 0xd9, - 0x03, 0x2f, 0x60, 0x22, 0x31, 0x64, 0xea, 0x44, 0x06, 0x5f, 0x53, 0x74, 0x1c, 0x49, 0xa0, 0x2a, - 0xa4, 0x7d, 0x8f, 0xb2, 0x20, 0x3f, 0x23, 0x0c, 0x3e, 0x37, 0xd6, 0xe0, 0xaa, 0x47, 0x99, 0xea, - 0xa5, 0xf1, 0x88, 0xe2, 0x08, 0x58, 0x02, 0xe9, 0x5f, 0xc0, 0x0b, 0x43, 0x2c, 0x97, 0x57, 0xd0, - 0x67, 0x90, 0xb1, 0x25, 0x53, 0x4d, 0xc4, 0xcb, 0x63, 0x15, 0x0e, 0xf1, 0x3f, 0x1e, 0xc4, 0xe1, - 0xc0, 0x0d, 0x51, 0xf5, 0xef, 0x35, 0x58, 0x1e, 0xb0, 0x54, 0xec, 0x12, 0x1e, 0x65, 0x22, 0x62, - 0xe9, 0xc4, 0x2e, 0xe1, 0x51, 0x86, 0x05, 0x07, 0x5d, 0x87, 0xac, 0x58, 0x45, 0x2c, 0xcf, 0x51, - 0x51, 0x2b, 0x87, 0x51, 0xab, 0x2a, 0xfa, 0x51, 0xa7, 0xf8, 0xe2, 0xe0, 0x7e, 0x56, 0x0a, 0xd9, - 0x38, 0x02, 0xe0, 0x55, 0x47, 0x28, 0xf5, 0xa8, 0x2a, 0x4c, 0x51, 0x75, 0x9b, 0x9c, 0x80, 0x25, - 0x5d, 0xff, 0x2e, 0x4e, 0x4a, 0xbe, 0x2b, 0x70, 0xfb, 0xf8, 0x8b, 0xf4, 0xcf, 0x72, 0xfe, 0x5e, - 0x58, 0x70, 0x90, 0x0f, 0x4b, 0x76, 0xdf, 0x72, 0x31, 0x71, 0xd3, 0x8d, 0x6e, 0x18, 0x79, 0x85, - 0xbc, 0xd4, 0xcf, 0xc1, 0x03, 0xe8, 0xfa, 0x2d, 0x18, 0x90, 0xe2, 0xed, 0xfe, 0x80, 0x31, 0x7f, - 0x48, 0xe1, 0x8c, 0xde, 0x66, 0x62, 0xed, 0x59, 0xe1, 0x53, 0xbd, 0x5e, 0xc5, 0x02, 0x45, 0xff, - 0x46, 0x83, 0x53, 0x43, 0x07, 0x67, 0xd4, 0xd8, 0xb4, 0x91, 0x8d, 0xad, 0xa2, 0x5e, 0x54, 0xc6, - 0xe0, 0xfc, 0x68, 0x4b, 0x7a, 0x91, 0xf9, 0x8b, 0x0f, 0x7b, 0x7f, 0xfd, 0xcf, 0x54, 0xf4, 0x22, - 0xa2, 0xab, 0xbd, 0x1b, 0xc5, 0x5b, 0x74, 0x1d, 0xae, 0x59, 0xf5, 0xd0, 0x93, 0x89, 0xf8, 0x45, - 0x3c, 0x3c, 0x20, 0x8d, 0x1a, 0xb0, 0xd8, 0x20, 0xfb, 0x66, 0xdb, 0x61, 0x4a, 0xb7, 0x8a, 0xda, - 0xe4, 0xeb, 0x26, 0xea, 0x76, 0x8a, 0x8b, 0x57, 0x7a, 0x30, 0x70, 0x1f, 0x26, 0xda, 0x80, 0x69, - 0xe6, 0x84, 0xed, 0xe6, 0x95, 0xb1, 0xd0, 0xf5, 0x9d, 0x9a, 0x91, 0x53, 0xee, 0x4f, 0xd7, 0x77, - 0x6a, 0x98, 0xdf, 0x46, 0xef, 0x43, 0x9a, 0xb6, 0x1d, 0xc2, 0x97, 0xa9, 0xe9, 0x89, 0xf6, 0x32, - 0xfe, 0xa6, 0x71, 0xf9, 0xf3, 0x53, 0x80, 0x25, 0x84, 0xfe, 0x25, 0x2c, 0xf4, 0x6c, 0x5c, 0xa8, - 0x05, 0xf3, 0x4e, 0xa2, 0x84, 0x55, 0x14, 0x2e, 0xfd, 0xaf, 0xba, 0x57, 0x0d, 0xe7, 0xa4, 0xd2, - 0x38, 0x9f, 0xe4, 0xe1, 0x1e, 0x78, 0xdd, 0x04, 0x88, 0x7d, 0xe5, 0x95, 0xc8, 0xcb, 0x47, 0x76, - 0x1b, 0x55, 0x89, 0xbc, 0xaa, 0x02, 0x2c, 0xe9, 0x7c, 0x7a, 0x05, 0xc4, 0xa2, 0x84, 0x55, 0xe2, - 0x7e, 0x19, 0x4d, 0xaf, 0x5a, 0xc4, 0xc1, 0x09, 0x29, 0xfd, 0x77, 0x0d, 0x16, 0x2a, 0xd2, 0xe4, - 0xaa, 0xe7, 0xd8, 0xd6, 0xbd, 0x63, 0x58, 0xb4, 0x6e, 0xf4, 0x2c, 0x5a, 0x4f, 0x68, 0xd3, 0x3d, - 0x86, 0x8d, 0xdc, 0xb4, 0x7e, 0xd2, 0xe0, 0xf9, 0x1e, 0xc9, 0xcd, 0xb8, 0x19, 0x45, 0x23, 0x41, - 0x1b, 0x37, 0x12, 0x7a, 0x10, 0x44, 0x69, 0x0d, 0x1d, 0x09, 0x68, 0x0b, 0x52, 0xcc, 0x53, 0x39, - 0x3a, 0x31, 0x1c, 0x21, 0x34, 0x9e, 0x6d, 0x75, 0x0f, 0xa7, 0x98, 0xa7, 0xff, 0xa2, 0x41, 0xbe, - 0x47, 0x2a, 0xd9, 0x44, 0x9f, 0xbd, 0xdd, 0x37, 0x60, 0x66, 0x9f, 0x7a, 0xad, 0xa7, 0xb1, 0x3c, - 0x0a, 0xfa, 0x55, 0xea, 0xb5, 0xb0, 0x80, 0xd1, 0xef, 0x6b, 0xb0, 0xdc, 0x23, 0x79, 0x0c, 0x0b, - 0xc9, 0x4e, 0xef, 0x42, 0x72, 0x76, 0x42, 0x1f, 0x46, 0xac, 0x25, 0xf7, 0x53, 0x7d, 0x1e, 0x70, - 0x5f, 0xd1, 0x3e, 0xe4, 0x7c, 0xaf, 0x51, 0x23, 0x0e, 0xb1, 0x98, 0x37, 0xac, 0xc0, 0x9f, 0xe4, - 0x84, 0xb9, 0x47, 0x9c, 0xf0, 0xaa, 0x71, 0xa2, 0xdb, 0x29, 0xe6, 0xaa, 0x31, 0x16, 0x4e, 0x02, - 0xa3, 0xbb, 0xb0, 0x1c, 0xed, 0xa2, 0x91, 0xb6, 0xd4, 0xd3, 0x6b, 0x3b, 0xd5, 0xed, 0x14, 0x97, - 0x2b, 0xfd, 0x88, 0x78, 0x50, 0x09, 0xba, 0x06, 0x19, 0xdb, 0x17, 0x9f, 0xdd, 0xea, 0x8b, 0xed, - 0x49, 0x8b, 0x9d, 0xfc, 0x3e, 0x97, 0x1f, 0x7f, 0xea, 0x80, 0xc3, 0xeb, 0xfa, 0x5f, 0xfd, 0x39, - 0xc0, 0x13, 0x0e, 0x6d, 0x25, 0xb6, 0x0f, 0x39, 0xf3, 0xce, 0x3d, 0xdd, 0xe6, 0xd1, 0x3b, 0x16, - 0x47, 0x37, 0xa1, 0x36, 0xb3, 0x9d, 0x92, 0xfc, 0x31, 0xa6, 0xb4, 0xed, 0xb2, 0x5d, 0x5a, 0x63, - 0xd4, 0x76, 0x9b, 0x72, 0x44, 0x27, 0xd6, 0xa2, 0xd3, 0x90, 0x51, 0x53, 0x53, 0x38, 0x9e, 0x96, - 0x5e, 0x6d, 0x4a, 0x12, 0x0e, 0x79, 0xfa, 0x51, 0x7f, 0x5e, 0x88, 0x19, 0x7a, 0xfb, 0x99, 0xe5, - 0xc5, 0x73, 0x2a, 0x1b, 0x47, 0xe7, 0xc6, 0x27, 0xf1, 0x62, 0x29, 0x33, 0x7d, 0x7d, 0xc2, 0x4c, - 0x4f, 0x4e, 0xb4, 0x91, 0x6b, 0x25, 0xfa, 0x10, 0x66, 0x89, 0x44, 0x97, 0x23, 0xf2, 0xe2, 0x84, - 0xe8, 0x71, 0x5b, 0x8d, 0x7f, 0x79, 0x50, 0x34, 0x05, 0x88, 0xde, 0xe1, 0x51, 0xe2, 0xb2, 0xfc, - 0x83, 0x5f, 0xee, 0xe1, 0x73, 0xc6, 0x4b, 0xd2, 0xd9, 0x88, 0x7c, 0xc4, 0x3f, 0x70, 0xa2, 0x23, - 0x4e, 0xde, 0xd0, 0x3f, 0x05, 0x34, 0xb8, 0xe4, 0x4c, 0xb0, 0x42, 0x9d, 0x81, 0x59, 0xb7, 0xdd, - 0xda, 0x23, 0xb2, 0x86, 0xd2, 0xb1, 0x81, 0x15, 0x41, 0xc5, 0x8a, 0x6b, 0xbc, 0xfd, 0xe0, 0x71, - 0x61, 0xea, 0xe1, 0xe3, 0xc2, 0xd4, 0xa3, 0xc7, 0x85, 0xa9, 0xaf, 0xba, 0x05, 0xed, 0x41, 0xb7, - 0xa0, 0x3d, 0xec, 0x16, 0xb4, 0x47, 0xdd, 0x82, 0xf6, 0x4f, 0xb7, 0xa0, 0x7d, 0xfb, 0x6f, 0x61, - 0xea, 0xa3, 0xfc, 0xa8, 0x5f, 0x4b, 0xff, 0x0b, 0x00, 0x00, 0xff, 0xff, 0x24, 0x03, 0xec, 0x04, - 0x48, 0x15, 0x00, 0x00, + // 1884 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x59, 0xcd, 0x8f, 0x1b, 0x49, + 0x15, 0x9f, 0xf6, 0x8c, 0x67, 0xec, 0xe7, 0xf9, 0xc8, 0x14, 0x59, 0x61, 0x06, 0x61, 0x87, 0x5e, + 0xb2, 0x3b, 0x4b, 0x76, 0x6d, 0x32, 0x1b, 0x21, 0xb8, 0x00, 0xdb, 0x93, 0x6c, 0xe2, 0xcd, 0xc4, + 0xb1, 0xca, 0x56, 0x10, 0x88, 0x8f, 0xed, 0x69, 0xd7, 0x78, 0x7a, 0xa7, 0xdd, 0xd5, 0xaa, 0x2e, + 0x87, 0x44, 0x42, 0x88, 0x0b, 0x07, 0x6e, 0xf0, 0x27, 0x20, 0xfe, 0x02, 0x04, 0xd2, 0xae, 0xb4, + 0x82, 0x85, 0x0b, 0xca, 0x71, 0x25, 0x2e, 0x7b, 0xc1, 0x22, 0xe6, 0xbf, 0xc8, 0x09, 0xd5, 0x47, + 0x7f, 0xd9, 0xee, 0xb1, 0x89, 0x22, 0x9f, 0xc6, 0xfd, 0xde, 0xab, 0xdf, 0x7b, 0xf5, 0xea, 0x7d, + 0x55, 0x0d, 0x1c, 0x5e, 0x7c, 0x27, 0x6c, 0xb8, 0xb4, 0x69, 0x07, 0x6e, 0xd3, 0x27, 0xfc, 0x17, + 0x94, 0x5d, 0xb8, 0xfe, 0xa0, 0xf9, 0xf8, 0x66, 0x73, 0x40, 0x7c, 0xc2, 0x6c, 0x4e, 0xfa, 0x8d, + 0x80, 0x51, 0x4e, 0x51, 0x55, 0x49, 0x36, 0xec, 0xc0, 0x6d, 0x24, 0x92, 0x8d, 0xc7, 0x37, 0x0f, + 0xde, 0x19, 0xb8, 0xfc, 0x7c, 0x74, 0xda, 0x70, 0xe8, 0xb0, 0x39, 0xa0, 0x03, 0xda, 0x94, 0x0b, + 0x4e, 0x47, 0x67, 0xf2, 0x4b, 0x7e, 0xc8, 0x5f, 0x0a, 0xe8, 0xc0, 0x4c, 0xa9, 0x74, 0x28, 0x23, + 0x73, 0x94, 0x1d, 0xdc, 0x4a, 0x64, 0x86, 0xb6, 0x73, 0xee, 0xfa, 0x84, 0x3d, 0x6d, 0x06, 0x17, + 0x03, 0x41, 0x08, 0x9b, 0x43, 0xc2, 0xed, 0x79, 0xab, 0x9a, 0x79, 0xab, 0xd8, 0xc8, 0xe7, 0xee, + 0x90, 0xcc, 0x2c, 0xf8, 0xf6, 0xa2, 0x05, 0xa1, 0x73, 0x4e, 0x86, 0xf6, 0xcc, 0xba, 0x77, 0xf3, + 0xd6, 0x8d, 0xb8, 0xeb, 0x35, 0x5d, 0x9f, 0x87, 0x9c, 0x4d, 0x2f, 0x32, 0xff, 0x66, 0xc0, 0xde, + 0xbd, 0x5e, 0xaf, 0xd3, 0xf2, 0x07, 0x8c, 0x84, 0x61, 0xc7, 0xe6, 0xe7, 0xe8, 0x1a, 0x6c, 0x04, + 0x36, 0x3f, 0xaf, 0x1a, 0xd7, 0x8c, 0xc3, 0xb2, 0xb5, 0xfd, 0x6c, 0x5c, 0x5f, 0x9b, 0x8c, 0xeb, + 0x1b, 0x82, 0x87, 0x25, 0x07, 0xdd, 0x82, 0x92, 0xf8, 0xdb, 0x7b, 0x1a, 0x90, 0xea, 0xba, 0x94, + 0xaa, 0x4e, 0xc6, 0xf5, 0x52, 0x47, 0xd3, 0x5e, 0xa4, 0x7e, 0xe3, 0x58, 0x12, 0x75, 0x61, 0xeb, + 0xd4, 0x76, 0x2e, 0x88, 0xdf, 0xaf, 0x16, 0xae, 0x19, 0x87, 0x95, 0xa3, 0xc3, 0x46, 0xde, 0xf1, + 0x35, 0xb4, 0x3d, 0x96, 0x92, 0xb7, 0xf6, 0xb4, 0x11, 0x5b, 0x9a, 0x80, 0x23, 0x24, 0xf3, 0x0c, + 0xae, 0xa6, 0xec, 0xc7, 0x23, 0x8f, 0x3c, 0xb2, 0xbd, 0x11, 0x41, 0x6d, 0x28, 0x0a, 0xc5, 0x61, + 0xd5, 0xb8, 0xb6, 0x7e, 0x58, 0x39, 0x7a, 0x2b, 0x5f, 0xd5, 0xd4, 0xf6, 0xad, 0x1d, 0xad, 0xab, + 0x28, 0xbe, 0x42, 0xac, 0x60, 0xcc, 0x4f, 0x0c, 0x28, 0xb7, 0x3a, 0xef, 0xf5, 0xfb, 0x42, 0x0e, + 0x7d, 0x08, 0x25, 0x71, 0xde, 0x7d, 0x9b, 0xdb, 0xd2, 0x4d, 0x95, 0xa3, 0x6f, 0xa5, 0x14, 0xc4, + 0xee, 0x6f, 0x04, 0x17, 0x03, 0x41, 0x08, 0x1b, 0x42, 0x5a, 0x28, 0x7b, 0x78, 0xfa, 0x11, 0x71, + 0xf8, 0x03, 0xc2, 0x6d, 0x0b, 0x69, 0x3d, 0x90, 0xd0, 0x70, 0x8c, 0x8a, 0x5a, 0xb0, 0x11, 0x06, + 0xc4, 0xd1, 0x9e, 0x7a, 0xf3, 0x12, 0x4f, 0x45, 0x46, 0x75, 0x03, 0xe2, 0x24, 0xa7, 0x25, 0xbe, + 0xb0, 0x84, 0x30, 0x3f, 0x36, 0x60, 0x27, 0x96, 0x3a, 0x71, 0x43, 0x8e, 0x7e, 0x32, 0x63, 0x7e, + 0x63, 0x39, 0xf3, 0xc5, 0x6a, 0x69, 0xfc, 0x15, 0xad, 0xa7, 0x14, 0x51, 0x52, 0xa6, 0xdf, 0x83, + 0xa2, 0xcb, 0xc9, 0x30, 0xac, 0x16, 0xa4, 0xeb, 0x5f, 0x5f, 0xc2, 0xf6, 0xc4, 0xe9, 0x2d, 0xb1, + 0x12, 0x2b, 0x00, 0x73, 0x90, 0x32, 0x5c, 0x6c, 0x08, 0x3d, 0x82, 0x72, 0x60, 0x33, 0xe2, 0x73, + 0x4c, 0xce, 0xb4, 0xe5, 0x97, 0x9c, 0x6c, 0x27, 0x12, 0x25, 0x8c, 0xf8, 0x0e, 0xb1, 0x76, 0x26, + 0xe3, 0x7a, 0x39, 0x26, 0xe2, 0x04, 0xca, 0x7c, 0x08, 0x5b, 0xad, 0x8e, 0xe5, 0x51, 0xe7, 0x42, + 0x44, 0xbf, 0xe3, 0xf6, 0xd9, 0x74, 0xf4, 0x1f, 0xb7, 0x6e, 0x63, 0x2c, 0x39, 0xc8, 0x84, 0x4d, + 0xf2, 0xc4, 0x21, 0x01, 0x97, 0x1b, 0x2c, 0x5b, 0x30, 0x19, 0xd7, 0x37, 0xef, 0x48, 0x0a, 0xd6, + 0x1c, 0xf3, 0x37, 0x05, 0xd8, 0xd2, 0x41, 0xb5, 0x82, 0x60, 0xb9, 0x9b, 0x09, 0x96, 0xeb, 0x0b, + 0xd3, 0x2a, 0x2f, 0x54, 0xd0, 0x43, 0xd8, 0x0c, 0xb9, 0xcd, 0x47, 0xa1, 0x4c, 0xeb, 0xcb, 0xe3, + 0x4e, 0x43, 0x49, 0x71, 0x6b, 0x57, 0x83, 0x6d, 0xaa, 0x6f, 0xac, 0x61, 0xcc, 0x7f, 0x18, 0xb0, + 0x9b, 0xcd, 0x65, 0xf4, 0x08, 0xb6, 0x42, 0xc2, 0x1e, 0xbb, 0x0e, 0xa9, 0x6e, 0x48, 0x25, 0xcd, + 0xc5, 0x4a, 0x94, 0x7c, 0x54, 0x0d, 0x2a, 0xa2, 0x12, 0x68, 0x1a, 0x8e, 0xc0, 0xd0, 0x0f, 0xa1, + 0xc4, 0x48, 0x48, 0x47, 0xcc, 0x21, 0xda, 0xfa, 0x77, 0xd2, 0xc0, 0xa2, 0xaa, 0x0b, 0x48, 0x51, + 0x8a, 0xfa, 0x27, 0xd4, 0xb1, 0x3d, 0xe5, 0xca, 0x24, 0x3c, 0xb6, 0x45, 0x3c, 0x63, 0x0d, 0x81, + 0x63, 0x30, 0x51, 0x23, 0xb7, 0xb5, 0x21, 0xc7, 0x9e, 0xbd, 0x92, 0x03, 0x3d, 0xc9, 0x1c, 0xe8, + 0x37, 0x17, 0x3a, 0x48, 0xda, 0x95, 0x5b, 0x00, 0xfe, 0x6a, 0xc0, 0x95, 0xb4, 0xe0, 0x0a, 0x6a, + 0xc0, 0xfd, 0x6c, 0x0d, 0x78, 0x63, 0xb9, 0x1d, 0xe4, 0x94, 0x81, 0x7f, 0x1b, 0x50, 0x4f, 0x8b, + 0x75, 0x6c, 0x66, 0x0f, 0x09, 0x27, 0x2c, 0x8c, 0x0f, 0x0f, 0x1d, 0x42, 0xc9, 0xee, 0xb4, 0xee, + 0x32, 0x3a, 0x0a, 0xa2, 0xd4, 0x15, 0xa6, 0xbd, 0xa7, 0x69, 0x38, 0xe6, 0x8a, 0x04, 0xbf, 0x70, + 0x75, 0x0f, 0x4a, 0x25, 0xf8, 0x7d, 0xd7, 0xef, 0x63, 0xc9, 0x11, 0x12, 0xbe, 0x3d, 0x8c, 0x5a, + 0x5b, 0x2c, 0xd1, 0xb6, 0x87, 0x04, 0x4b, 0x0e, 0xaa, 0x43, 0x31, 0x74, 0x68, 0xa0, 0x22, 0xb8, + 0x6c, 0x95, 0x85, 0xc9, 0x5d, 0x41, 0xc0, 0x8a, 0x8e, 0x6e, 0x40, 0x59, 0x08, 0x86, 0x81, 0xed, + 0x90, 0x6a, 0x51, 0x0a, 0xc9, 0xea, 0xd3, 0x8e, 0x88, 0x38, 0xe1, 0x9b, 0x7f, 0x9a, 0x3a, 0x1f, + 0x59, 0xea, 0x8e, 0x00, 0x1c, 0xea, 0x73, 0x46, 0x3d, 0x8f, 0x44, 0xd5, 0x28, 0x0e, 0x9a, 0xe3, + 0x98, 0x83, 0x53, 0x52, 0xc8, 0x05, 0x08, 0x62, 0xdf, 0xe8, 0xe0, 0xf9, 0xee, 0x72, 0xae, 0x9f, + 0xe3, 0x53, 0x6b, 0x57, 0xa8, 0x4a, 0x31, 0x52, 0xe0, 0xe6, 0x9f, 0x0d, 0xa8, 0xe8, 0xf5, 0x2b, + 0x08, 0xa7, 0xf7, 0xb3, 0xe1, 0xf4, 0xf5, 0xc5, 0x83, 0xc3, 0xfc, 0x48, 0xfa, 0xc4, 0x80, 0x83, + 0xc8, 0x6a, 0x6a, 0xf7, 0x2d, 0xdb, 0xb3, 0x7d, 0x87, 0xb0, 0xa8, 0x52, 0x1f, 0x40, 0xc1, 0x8d, + 0xc2, 0x07, 0x34, 0x40, 0xa1, 0xd5, 0xc1, 0x05, 0x37, 0x40, 0x6f, 0x43, 0xe9, 0x9c, 0x86, 0x5c, + 0x06, 0x86, 0x0a, 0x9d, 0xd8, 0xe0, 0x7b, 0x9a, 0x8e, 0x63, 0x09, 0xd4, 0x81, 0x62, 0x40, 0x19, + 0x0f, 0xab, 0x1b, 0xd2, 0xe0, 0x1b, 0x0b, 0x0d, 0xee, 0x50, 0xc6, 0x75, 0x2d, 0x4d, 0x06, 0x10, + 0x81, 0x80, 0x15, 0x90, 0xf9, 0x4b, 0xf8, 0xca, 0x1c, 0xcb, 0xd5, 0x12, 0xf4, 0x73, 0xd8, 0x72, + 0x15, 0x53, 0xcf, 0x3b, 0xb7, 0x16, 0x2a, 0x9c, 0xb3, 0xff, 0x64, 0xcc, 0x8a, 0xc6, 0xa9, 0x08, + 0xd5, 0xfc, 0xa3, 0x01, 0xfb, 0x33, 0x96, 0xca, 0x49, 0x91, 0x32, 0x2e, 0x3d, 0x56, 0x4c, 0x4d, + 0x8a, 0x94, 0x71, 0x2c, 0x39, 0xe8, 0x3e, 0x94, 0xe4, 0xa0, 0xe9, 0x50, 0x4f, 0x7b, 0xad, 0x19, + 0x79, 0xad, 0xa3, 0xe9, 0x2f, 0xc6, 0xf5, 0xaf, 0xce, 0x4e, 0xdf, 0x8d, 0x88, 0x8d, 0x63, 0x00, + 0x91, 0x75, 0x84, 0x31, 0xca, 0x74, 0x62, 0xca, 0xac, 0xbb, 0x23, 0x08, 0x58, 0xd1, 0xcd, 0x3f, + 0x24, 0x41, 0x29, 0x26, 0x41, 0x61, 0x9f, 0x38, 0x91, 0xe9, 0x5e, 0x2e, 0xce, 0x0b, 0x4b, 0x0e, + 0x0a, 0xe0, 0x8a, 0x3b, 0x35, 0x3a, 0x2e, 0x5d, 0x74, 0xe3, 0x15, 0x56, 0x55, 0x23, 0x5f, 0x99, + 0xe6, 0xe0, 0x19, 0x74, 0xf3, 0x43, 0x98, 0x91, 0x12, 0xe5, 0xfe, 0x9c, 0xf3, 0x60, 0x4e, 0xe2, + 0xe4, 0xcf, 0xaa, 0x89, 0xf6, 0x92, 0xdc, 0x53, 0xaf, 0xd7, 0xc1, 0x12, 0xc5, 0xfc, 0xad, 0x01, + 0xaf, 0xcd, 0x6d, 0x9c, 0x71, 0x61, 0x33, 0x72, 0x0b, 0x5b, 0x5b, 0x9f, 0xa8, 0xf2, 0xc1, 0xdb, + 0xf9, 0x96, 0x64, 0x91, 0xc5, 0x89, 0xcf, 0x3b, 0x7f, 0xf3, 0x9f, 0x85, 0xf8, 0x44, 0x64, 0x55, + 0xfb, 0x41, 0xec, 0x6f, 0x59, 0x75, 0x84, 0x66, 0x5d, 0x43, 0xaf, 0xa6, 0xfc, 0x17, 0xf3, 0xf0, + 0x8c, 0x34, 0xea, 0xc3, 0x6e, 0x9f, 0x9c, 0xd9, 0x23, 0x8f, 0x6b, 0xdd, 0xda, 0x6b, 0xcb, 0x5f, + 0x26, 0xd0, 0x64, 0x5c, 0xdf, 0xbd, 0x9d, 0xc1, 0xc0, 0x53, 0x98, 0xe8, 0x18, 0xd6, 0xb9, 0x17, + 0x95, 0x9b, 0x6f, 0x2c, 0x84, 0xee, 0x9d, 0x74, 0xad, 0x8a, 0xde, 0xfe, 0x7a, 0xef, 0xa4, 0x8b, + 0xc5, 0x6a, 0xf4, 0x01, 0x14, 0xd9, 0xc8, 0x23, 0x62, 0x98, 0x5a, 0x5f, 0x6a, 0x2e, 0x13, 0x67, + 0x9a, 0xa4, 0xbf, 0xf8, 0x0a, 0xb1, 0x82, 0x30, 0x7f, 0x05, 0x3b, 0x99, 0x89, 0x0b, 0x0d, 0x61, + 0xdb, 0x4b, 0xa5, 0xb0, 0xf6, 0xc2, 0xbb, 0xff, 0x57, 0xde, 0xeb, 0x82, 0x73, 0x55, 0x6b, 0xdc, + 0x4e, 0xf3, 0x70, 0x06, 0xde, 0xb4, 0x01, 0x92, 0xbd, 0x8a, 0x4c, 0x14, 0xe9, 0xa3, 0xaa, 0x8d, + 0xce, 0x44, 0x91, 0x55, 0x21, 0x56, 0x74, 0xd1, 0xbd, 0x42, 0xe2, 0x30, 0xc2, 0xdb, 0x49, 0xbd, + 0x8c, 0xbb, 0x57, 0x37, 0xe6, 0xe0, 0x94, 0x94, 0xf9, 0x77, 0x03, 0x76, 0xda, 0xca, 0xe4, 0x0e, + 0xf5, 0x5c, 0xe7, 0xe9, 0x0a, 0x06, 0xad, 0x07, 0x99, 0x41, 0xeb, 0x92, 0x32, 0x9d, 0x31, 0x2c, + 0x77, 0xd2, 0xfa, 0x8b, 0x01, 0x5f, 0xce, 0x48, 0xde, 0x49, 0x8a, 0x51, 0xdc, 0x12, 0x8c, 0x45, + 0x2d, 0x21, 0x83, 0x20, 0x53, 0x6b, 0x6e, 0x4b, 0x40, 0x77, 0xa1, 0xc0, 0xa9, 0x8e, 0xd1, 0xa5, + 0xe1, 0x08, 0x61, 0x49, 0x6f, 0xeb, 0x51, 0x5c, 0xe0, 0xd4, 0xfc, 0xd4, 0x80, 0x6a, 0x46, 0x2a, + 0x5d, 0x44, 0x5f, 0xbd, 0xdd, 0x0f, 0x60, 0xe3, 0x8c, 0xd1, 0xe1, 0xcb, 0x58, 0x1e, 0x3b, 0xfd, + 0x7d, 0x46, 0x87, 0x58, 0xc2, 0x98, 0x9f, 0x19, 0xb0, 0x9f, 0x91, 0x5c, 0xc1, 0x40, 0x72, 0x92, + 0x1d, 0x48, 0xde, 0x5c, 0x72, 0x0f, 0x39, 0x63, 0xc9, 0x67, 0x85, 0xa9, 0x1d, 0x88, 0xbd, 0xa2, + 0x33, 0xa8, 0x04, 0xb4, 0xdf, 0x25, 0x1e, 0x71, 0x38, 0x9d, 0x97, 0xe0, 0x97, 0x6d, 0xc2, 0x3e, + 0x25, 0x5e, 0xb4, 0xd4, 0xda, 0x9b, 0x8c, 0xeb, 0x95, 0x4e, 0x82, 0x85, 0xd3, 0xc0, 0xe8, 0x09, + 0xec, 0xc7, 0xb3, 0x68, 0xac, 0xad, 0xf0, 0xf2, 0xda, 0x5e, 0x9b, 0x8c, 0xeb, 0xfb, 0xed, 0x69, + 0x44, 0x3c, 0xab, 0x04, 0xdd, 0x83, 0x2d, 0x37, 0x90, 0xd7, 0x6e, 0x7d, 0x63, 0xbb, 0x6c, 0xb0, + 0x53, 0xf7, 0x73, 0x75, 0xf9, 0xd3, 0x1f, 0x38, 0x5a, 0x6e, 0xfe, 0x6b, 0x3a, 0x06, 0x44, 0xc0, + 0xa1, 0xbb, 0xa9, 0xe9, 0x43, 0xf5, 0xbc, 0x1b, 0x2f, 0x37, 0x79, 0x64, 0xdb, 0x62, 0x7e, 0x11, + 0x1a, 0x71, 0xd7, 0x6b, 0xa8, 0xa7, 0xb6, 0x46, 0xcb, 0xe7, 0x0f, 0x59, 0x97, 0x33, 0xd7, 0x1f, + 0xa8, 0x16, 0x9d, 0x1a, 0x8b, 0xae, 0xc3, 0x96, 0xee, 0x9a, 0x72, 0xe3, 0x45, 0xb5, 0xab, 0x3b, + 0x8a, 0x84, 0x23, 0x9e, 0xf9, 0x62, 0x3a, 0x2e, 0x64, 0x0f, 0xfd, 0xe8, 0x95, 0xc5, 0xc5, 0x97, + 0x74, 0x34, 0xe6, 0xc7, 0xc6, 0x4f, 0x93, 0xc1, 0x52, 0x45, 0xfa, 0xd1, 0x92, 0x91, 0x9e, 0xee, + 0x68, 0xb9, 0x63, 0x25, 0xfa, 0x11, 0x6c, 0x12, 0x85, 0xae, 0x5a, 0xe4, 0xcd, 0x25, 0xd1, 0x93, + 0xb2, 0x9a, 0xbc, 0x3c, 0x68, 0x9a, 0x06, 0x44, 0xdf, 0x17, 0x5e, 0x12, 0xb2, 0xe2, 0xc2, 0xaf, + 0xe6, 0xf0, 0xb2, 0xf5, 0x35, 0xb5, 0xd9, 0x98, 0xfc, 0x42, 0x5c, 0x70, 0xe2, 0x4f, 0x9c, 0x5e, + 0x61, 0x7e, 0x6c, 0xc0, 0xde, 0xd4, 0x0b, 0x12, 0x7a, 0x1d, 0x8a, 0x83, 0xd4, 0x15, 0x33, 0xce, + 0x66, 0x75, 0xc7, 0x54, 0x3c, 0x71, 0x53, 0x88, 0x1f, 0x22, 0xa6, 0x6e, 0x0a, 0xb3, 0xaf, 0x0b, + 0xa8, 0x99, 0xbe, 0x29, 0xaa, 0xc1, 0x76, 0x5f, 0x8b, 0xcf, 0xbd, 0x2d, 0xc6, 0x43, 0xdc, 0x46, + 0xde, 0x10, 0x67, 0xfe, 0x0c, 0xd0, 0xec, 0x78, 0xb6, 0xc4, 0xf0, 0xf7, 0x06, 0x6c, 0xfa, 0xa3, + 0xe1, 0x29, 0x51, 0xd9, 0x5f, 0x4c, 0x5c, 0xdb, 0x96, 0x54, 0xac, 0xb9, 0xe6, 0xef, 0x0b, 0x50, + 0xd1, 0x0a, 0x8e, 0x5b, 0xb7, 0xf1, 0x0a, 0xda, 0xf4, 0xfd, 0x4c, 0x9b, 0x7e, 0x6b, 0xe1, 0x58, + 0x2a, 0xcc, 0xca, 0x7d, 0xe4, 0xea, 0x4e, 0x3d, 0x72, 0xdd, 0x58, 0x0e, 0xee, 0xf2, 0x87, 0xae, + 0x4f, 0x0d, 0xd8, 0x4b, 0x49, 0xaf, 0xa0, 0x05, 0x7d, 0x90, 0x6d, 0x41, 0xd7, 0x97, 0xda, 0x45, + 0x4e, 0x03, 0x3a, 0xca, 0x18, 0x2f, 0xab, 0x4c, 0x1d, 0x8a, 0x8e, 0xdb, 0x67, 0x99, 0x11, 0x4f, + 0x30, 0x43, 0xac, 0xe8, 0xe6, 0x13, 0xd8, 0x9f, 0x71, 0x0f, 0x72, 0xe4, 0xab, 0x45, 0xdf, 0xe5, + 0x2e, 0xf5, 0xa3, 0x89, 0xa1, 0xb9, 0xdc, 0xa6, 0x8f, 0xa3, 0x75, 0x99, 0x67, 0x0e, 0x0d, 0x85, + 0x53, 0xb0, 0xd6, 0xf7, 0x9e, 0x3d, 0xaf, 0xad, 0x7d, 0xfe, 0xbc, 0xb6, 0xf6, 0xc5, 0xf3, 0xda, + 0xda, 0xaf, 0x27, 0x35, 0xe3, 0xd9, 0xa4, 0x66, 0x7c, 0x3e, 0xa9, 0x19, 0x5f, 0x4c, 0x6a, 0xc6, + 0x7f, 0x26, 0x35, 0xe3, 0x77, 0xff, 0xad, 0xad, 0xfd, 0xb8, 0x9a, 0xf7, 0x5f, 0xa4, 0xff, 0x05, + 0x00, 0x00, 0xff, 0xff, 0xb5, 0x6b, 0x8c, 0x52, 0x60, 0x1a, 0x00, 0x00, } func (m *HTTPIngressPath) Marshal() (dAtA []byte, err error) { @@ -1028,7 +1274,7 @@ func (m *HTTPIngressRuleValue) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *IPBlock) Marshal() (dAtA []byte, err error) { +func (m *IPAddress) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1038,34 +1284,40 @@ func (m *IPBlock) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *IPBlock) MarshalTo(dAtA []byte) (int, error) { +func (m *IPAddress) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *IPBlock) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *IPAddress) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if len(m.Except) > 0 { - for iNdEx := len(m.Except) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.Except[iNdEx]) - copy(dAtA[i:], m.Except[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Except[iNdEx]))) - i-- - dAtA[i] = 0x12 + { + size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } - i -= len(m.CIDR) - copy(dAtA[i:], m.CIDR) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.CIDR))) i-- dAtA[i] = 0xa return len(dAtA) - i, nil } -func (m *Ingress) Marshal() (dAtA []byte, err error) { +func (m *IPAddressList) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1075,38 +1327,32 @@ func (m *Ingress) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *Ingress) MarshalTo(dAtA []byte) (int, error) { +func (m *IPAddressList) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *Ingress) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *IPAddressList) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - { - size, err := m.Status.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - { - size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err + if len(m.Items) > 0 { + for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) } - i-- - dAtA[i] = 0x12 { - size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -1118,7 +1364,7 @@ func (m *Ingress) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *IngressBackend) Marshal() (dAtA []byte, err error) { +func (m *IPAddressSpec) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1128,19 +1374,19 @@ func (m *IngressBackend) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *IngressBackend) MarshalTo(dAtA []byte) (int, error) { +func (m *IPAddressSpec) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *IngressBackend) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *IPAddressSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if m.Service != nil { + if m.ParentRef != nil { { - size, err := m.Service.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.ParentRef.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -1148,15 +1394,140 @@ func (m *IngressBackend) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenerated(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x22 + dAtA[i] = 0xa } - if m.Resource != nil { - { - size, err := m.Resource.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size + return len(dAtA) - i, nil +} + +func (m *IPBlock) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *IPBlock) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *IPBlock) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Except) > 0 { + for iNdEx := len(m.Except) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Except[iNdEx]) + copy(dAtA[i:], m.Except[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Except[iNdEx]))) + i-- + dAtA[i] = 0x12 + } + } + i -= len(m.CIDR) + copy(dAtA[i:], m.CIDR) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.CIDR))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *Ingress) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Ingress) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Ingress) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Status.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + { + size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *IngressBackend) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *IngressBackend) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *IngressBackend) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Service != nil { + { + size, err := m.Service.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + if m.Resource != nil { + { + size, err := m.Resource.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size i = encodeVarintGenerated(dAtA, i, uint64(size)) } i-- @@ -2137,6 +2508,49 @@ func (m *NetworkPolicySpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *ParentReference) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ParentReference) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ParentReference) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0x22 + i -= len(m.Namespace) + copy(dAtA[i:], m.Namespace) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Namespace))) + i-- + dAtA[i] = 0x1a + i -= len(m.Resource) + copy(dAtA[i:], m.Resource) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Resource))) + i-- + dAtA[i] = 0x12 + i -= len(m.Group) + copy(dAtA[i:], m.Group) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Group))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *ServiceBackendPort) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -2168,72 +2582,284 @@ func (m *ServiceBackendPort) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int { - offset -= sovGenerated(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ +func (m *ServiceCIDR) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - dAtA[offset] = uint8(v) - return base + return dAtA[:n], nil } -func (m *HTTPIngressPath) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Path) - n += 1 + l + sovGenerated(uint64(l)) - l = m.Backend.Size() - n += 1 + l + sovGenerated(uint64(l)) - if m.PathType != nil { - l = len(*m.PathType) - n += 1 + l + sovGenerated(uint64(l)) - } - return n + +func (m *ServiceCIDR) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *HTTPIngressRuleValue) Size() (n int) { - if m == nil { - return 0 - } +func (m *ServiceCIDR) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - if len(m.Paths) > 0 { - for _, e := range m.Paths { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) + { + size, err := m.Status.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } - return n -} - -func (m *IPBlock) Size() (n int) { - if m == nil { - return 0 + i-- + dAtA[i] = 0x1a + { + size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } - var l int - _ = l - l = len(m.CIDR) - n += 1 + l + sovGenerated(uint64(l)) - if len(m.Except) > 0 { - for _, s := range m.Except { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) + i-- + dAtA[i] = 0x12 + { + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } - return n + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil } -func (m *Ingress) Size() (n int) { - if m == nil { - return 0 +func (m *ServiceCIDRList) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - var l int - _ = l + return dAtA[:n], nil +} + +func (m *ServiceCIDRList) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ServiceCIDRList) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Items) > 0 { + for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ServiceCIDRSpec) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ServiceCIDRSpec) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ServiceCIDRSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.CIDRs) > 0 { + for iNdEx := len(m.CIDRs) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.CIDRs[iNdEx]) + copy(dAtA[i:], m.CIDRs[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.CIDRs[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *ServiceCIDRStatus) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ServiceCIDRStatus) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ServiceCIDRStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Conditions) > 0 { + for iNdEx := len(m.Conditions) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Conditions[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int { + offset -= sovGenerated(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *HTTPIngressPath) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Path) + n += 1 + l + sovGenerated(uint64(l)) + l = m.Backend.Size() + n += 1 + l + sovGenerated(uint64(l)) + if m.PathType != nil { + l = len(*m.PathType) + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + +func (m *HTTPIngressRuleValue) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Paths) > 0 { + for _, e := range m.Paths { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *IPAddress) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Spec.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *IPAddressList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ListMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Items) > 0 { + for _, e := range m.Items { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *IPAddressSpec) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ParentRef != nil { + l = m.ParentRef.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + +func (m *IPBlock) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.CIDR) + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Except) > 0 { + for _, s := range m.Except { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *Ingress) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l l = m.ObjectMeta.Size() n += 1 + l + sovGenerated(uint64(l)) l = m.Spec.Size() @@ -2635,6 +3261,23 @@ func (m *NetworkPolicySpec) Size() (n int) { return n } +func (m *ParentReference) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Group) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Resource) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Namespace) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + func (m *ServiceBackendPort) Size() (n int) { if m == nil { return 0 @@ -2647,39 +3290,138 @@ func (m *ServiceBackendPort) Size() (n int) { return n } -func sovGenerated(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozGenerated(x uint64) (n int) { - return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (this *HTTPIngressPath) String() string { - if this == nil { - return "nil" +func (m *ServiceCIDR) Size() (n int) { + if m == nil { + return 0 } - s := strings.Join([]string{`&HTTPIngressPath{`, - `Path:` + fmt.Sprintf("%v", this.Path) + `,`, - `Backend:` + strings.Replace(strings.Replace(this.Backend.String(), "IngressBackend", "IngressBackend", 1), `&`, ``, 1) + `,`, - `PathType:` + valueToStringGenerated(this.PathType) + `,`, - `}`, - }, "") - return s + var l int + _ = l + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Spec.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Status.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n } -func (this *HTTPIngressRuleValue) String() string { - if this == nil { - return "nil" + +func (m *ServiceCIDRList) Size() (n int) { + if m == nil { + return 0 } - repeatedStringForPaths := "[]HTTPIngressPath{" - for _, f := range this.Paths { - repeatedStringForPaths += strings.Replace(strings.Replace(f.String(), "HTTPIngressPath", "HTTPIngressPath", 1), `&`, ``, 1) + "," + var l int + _ = l + l = m.ListMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Items) > 0 { + for _, e := range m.Items { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } } - repeatedStringForPaths += "}" + return n +} + +func (m *ServiceCIDRSpec) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.CIDRs) > 0 { + for _, s := range m.CIDRs { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *ServiceCIDRStatus) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Conditions) > 0 { + for _, e := range m.Conditions { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func sovGenerated(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGenerated(x uint64) (n int) { + return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (this *HTTPIngressPath) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&HTTPIngressPath{`, + `Path:` + fmt.Sprintf("%v", this.Path) + `,`, + `Backend:` + strings.Replace(strings.Replace(this.Backend.String(), "IngressBackend", "IngressBackend", 1), `&`, ``, 1) + `,`, + `PathType:` + valueToStringGenerated(this.PathType) + `,`, + `}`, + }, "") + return s +} +func (this *HTTPIngressRuleValue) String() string { + if this == nil { + return "nil" + } + repeatedStringForPaths := "[]HTTPIngressPath{" + for _, f := range this.Paths { + repeatedStringForPaths += strings.Replace(strings.Replace(f.String(), "HTTPIngressPath", "HTTPIngressPath", 1), `&`, ``, 1) + "," + } + repeatedStringForPaths += "}" s := strings.Join([]string{`&HTTPIngressRuleValue{`, `Paths:` + repeatedStringForPaths + `,`, `}`, }, "") return s } +func (this *IPAddress) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&IPAddress{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, + `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "IPAddressSpec", "IPAddressSpec", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *IPAddressList) String() string { + if this == nil { + return "nil" + } + repeatedStringForItems := "[]IPAddress{" + for _, f := range this.Items { + repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "IPAddress", "IPAddress", 1), `&`, ``, 1) + "," + } + repeatedStringForItems += "}" + s := strings.Join([]string{`&IPAddressList{`, + `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, + `Items:` + repeatedStringForItems + `,`, + `}`, + }, "") + return s +} +func (this *IPAddressSpec) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&IPAddressSpec{`, + `ParentRef:` + strings.Replace(this.ParentRef.String(), "ParentReference", "ParentReference", 1) + `,`, + `}`, + }, "") + return s +} func (this *IPBlock) String() string { if this == nil { return "nil" @@ -3018,6 +3760,19 @@ func (this *NetworkPolicySpec) String() string { }, "") return s } +func (this *ParentReference) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ParentReference{`, + `Group:` + fmt.Sprintf("%v", this.Group) + `,`, + `Resource:` + fmt.Sprintf("%v", this.Resource) + `,`, + `Namespace:` + fmt.Sprintf("%v", this.Namespace) + `,`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `}`, + }, "") + return s +} func (this *ServiceBackendPort) String() string { if this == nil { return "nil" @@ -3029,6 +3784,59 @@ func (this *ServiceBackendPort) String() string { }, "") return s } +func (this *ServiceCIDR) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ServiceCIDR{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, + `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "ServiceCIDRSpec", "ServiceCIDRSpec", 1), `&`, ``, 1) + `,`, + `Status:` + strings.Replace(strings.Replace(this.Status.String(), "ServiceCIDRStatus", "ServiceCIDRStatus", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *ServiceCIDRList) String() string { + if this == nil { + return "nil" + } + repeatedStringForItems := "[]ServiceCIDR{" + for _, f := range this.Items { + repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "ServiceCIDR", "ServiceCIDR", 1), `&`, ``, 1) + "," + } + repeatedStringForItems += "}" + s := strings.Join([]string{`&ServiceCIDRList{`, + `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, + `Items:` + repeatedStringForItems + `,`, + `}`, + }, "") + return s +} +func (this *ServiceCIDRSpec) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&ServiceCIDRSpec{`, + `CIDRs:` + fmt.Sprintf("%v", this.CIDRs) + `,`, + `}`, + }, "") + return s +} +func (this *ServiceCIDRStatus) String() string { + if this == nil { + return "nil" + } + repeatedStringForConditions := "[]Condition{" + for _, f := range this.Conditions { + repeatedStringForConditions += fmt.Sprintf("%v", f) + "," + } + repeatedStringForConditions += "}" + s := strings.Join([]string{`&ServiceCIDRStatus{`, + `Conditions:` + repeatedStringForConditions + `,`, + `}`, + }, "") + return s +} func valueToStringGenerated(v interface{}) string { rv := reflect.ValueOf(v) if rv.IsNil() { @@ -3269,7 +4077,7 @@ func (m *HTTPIngressRuleValue) Unmarshal(dAtA []byte) error { } return nil } -func (m *IPBlock) Unmarshal(dAtA []byte) error { +func (m *IPAddress) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3292,17 +4100,17 @@ func (m *IPBlock) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: IPBlock: wiretype end group for non-group") + return fmt.Errorf("proto: IPAddress: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: IPBlock: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: IPAddress: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CIDR", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -3312,29 +4120,30 @@ func (m *IPBlock) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.CIDR = string(dAtA[iNdEx:postIndex]) + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Except", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -3344,23 +4153,24 @@ func (m *IPBlock) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.Except = append(m.Except, string(dAtA[iNdEx:postIndex])) + if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -3383,7 +4193,7 @@ func (m *IPBlock) Unmarshal(dAtA []byte) error { } return nil } -func (m *Ingress) Unmarshal(dAtA []byte) error { +func (m *IPAddressList) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3406,15 +4216,15 @@ func (m *Ingress) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Ingress: wiretype end group for non-group") + return fmt.Errorf("proto: IPAddressList: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Ingress: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: IPAddressList: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -3441,46 +4251,13 @@ func (m *Ingress) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -3507,7 +4284,8 @@ func (m *Ingress) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Items = append(m.Items, IPAddress{}) + if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -3532,7 +4310,7 @@ func (m *Ingress) Unmarshal(dAtA []byte) error { } return nil } -func (m *IngressBackend) Unmarshal(dAtA []byte) error { +func (m *IPAddressSpec) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3555,51 +4333,15 @@ func (m *IngressBackend) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: IngressBackend: wiretype end group for non-group") + return fmt.Errorf("proto: IPAddressSpec: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: IngressBackend: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: IPAddressSpec: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Resource", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Resource == nil { - m.Resource = &v11.TypedLocalObjectReference{} - } - if err := m.Resource.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 4: + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Service", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ParentRef", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -3626,10 +4368,10 @@ func (m *IngressBackend) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Service == nil { - m.Service = &IngressServiceBackend{} + if m.ParentRef == nil { + m.ParentRef = &ParentReference{} } - if err := m.Service.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ParentRef.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -3654,7 +4396,7 @@ func (m *IngressBackend) Unmarshal(dAtA []byte) error { } return nil } -func (m *IngressClass) Unmarshal(dAtA []byte) error { +func (m *IPBlock) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3677,17 +4419,17 @@ func (m *IngressClass) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: IngressClass: wiretype end group for non-group") + return fmt.Errorf("proto: IPBlock: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: IngressClass: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: IPBlock: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field CIDR", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -3697,30 +4439,29 @@ func (m *IngressClass) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.CIDR = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Except", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -3730,24 +4471,23 @@ func (m *IngressClass) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Except = append(m.Except, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex @@ -3770,7 +4510,7 @@ func (m *IngressClass) Unmarshal(dAtA []byte) error { } return nil } -func (m *IngressClassList) Unmarshal(dAtA []byte) error { +func (m *Ingress) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3793,15 +4533,15 @@ func (m *IngressClassList) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: IngressClassList: wiretype end group for non-group") + return fmt.Errorf("proto: Ingress: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: IngressClassList: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Ingress: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -3828,13 +4568,13 @@ func (m *IngressClassList) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -3861,8 +4601,40 @@ func (m *IngressClassList) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Items = append(m.Items, IngressClass{}) - if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -3887,7 +4659,7 @@ func (m *IngressClassList) Unmarshal(dAtA []byte) error { } return nil } -func (m *IngressClassParametersReference) Unmarshal(dAtA []byte) error { +func (m *IngressBackend) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3910,50 +4682,17 @@ func (m *IngressClassParametersReference) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: IngressClassParametersReference: wiretype end group for non-group") + return fmt.Errorf("proto: IngressBackend: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: IngressClassParametersReference: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: IngressBackend: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field APIGroup", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(dAtA[iNdEx:postIndex]) - m.APIGroup = &s - iNdEx = postIndex - case 2: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Resource", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -3963,61 +4702,33 @@ func (m *IngressClassParametersReference) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.Kind = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated + if m.Resource == nil { + m.Resource = &v11.TypedLocalObjectReference{} } - if postIndex > l { - return io.ErrUnexpectedEOF + if err := m.Resource.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err } - m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Scope", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Service", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -4027,57 +4738,27 @@ func (m *IngressClassParametersReference) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - s := string(dAtA[iNdEx:postIndex]) - m.Scope = &s - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Namespace", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated + if m.Service == nil { + m.Service = &IngressServiceBackend{} } - if postIndex > l { - return io.ErrUnexpectedEOF + if err := m.Service.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err } - s := string(dAtA[iNdEx:postIndex]) - m.Namespace = &s iNdEx = postIndex default: iNdEx = preIndex @@ -4100,7 +4781,7 @@ func (m *IngressClassParametersReference) Unmarshal(dAtA []byte) error { } return nil } -func (m *IngressClassSpec) Unmarshal(dAtA []byte) error { +func (m *IngressClass) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4123,17 +4804,17 @@ func (m *IngressClassSpec) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: IngressClassSpec: wiretype end group for non-group") + return fmt.Errorf("proto: IngressClass: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: IngressClassSpec: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: IngressClass: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Controller", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -4143,27 +4824,28 @@ func (m *IngressClassSpec) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.Controller = string(dAtA[iNdEx:postIndex]) + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Parameters", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -4190,10 +4872,7 @@ func (m *IngressClassSpec) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Parameters == nil { - m.Parameters = &IngressClassParametersReference{} - } - if err := m.Parameters.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -4218,7 +4897,7 @@ func (m *IngressClassSpec) Unmarshal(dAtA []byte) error { } return nil } -func (m *IngressList) Unmarshal(dAtA []byte) error { +func (m *IngressClassList) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4241,10 +4920,10 @@ func (m *IngressList) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: IngressList: wiretype end group for non-group") + return fmt.Errorf("proto: IngressClassList: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: IngressList: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: IngressClassList: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -4309,7 +4988,7 @@ func (m *IngressList) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Items = append(m.Items, Ingress{}) + m.Items = append(m.Items, IngressClass{}) if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } @@ -4335,7 +5014,7 @@ func (m *IngressList) Unmarshal(dAtA []byte) error { } return nil } -func (m *IngressLoadBalancerIngress) Unmarshal(dAtA []byte) error { +func (m *IngressClassParametersReference) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4358,15 +5037,15 @@ func (m *IngressLoadBalancerIngress) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: IngressLoadBalancerIngress: wiretype end group for non-group") + return fmt.Errorf("proto: IngressClassParametersReference: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: IngressLoadBalancerIngress: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: IngressClassParametersReference: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field IP", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field APIGroup", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -4394,11 +5073,12 @@ func (m *IngressLoadBalancerIngress) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.IP = string(dAtA[iNdEx:postIndex]) + s := string(dAtA[iNdEx:postIndex]) + m.APIGroup = &s iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Hostname", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -4426,13 +5106,45 @@ func (m *IngressLoadBalancerIngress) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Hostname = string(dAtA[iNdEx:postIndex]) + m.Kind = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Ports", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Scope", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -4442,25 +5154,57 @@ func (m *IngressLoadBalancerIngress) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.Ports = append(m.Ports, IngressPortStatus{}) - if err := m.Ports[len(m.Ports)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + s := string(dAtA[iNdEx:postIndex]) + m.Scope = &s + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Namespace", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF } + s := string(dAtA[iNdEx:postIndex]) + m.Namespace = &s iNdEx = postIndex default: iNdEx = preIndex @@ -4483,7 +5227,7 @@ func (m *IngressLoadBalancerIngress) Unmarshal(dAtA []byte) error { } return nil } -func (m *IngressLoadBalancerStatus) Unmarshal(dAtA []byte) error { +func (m *IngressClassSpec) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4506,15 +5250,47 @@ func (m *IngressLoadBalancerStatus) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: IngressLoadBalancerStatus: wiretype end group for non-group") + return fmt.Errorf("proto: IngressClassSpec: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: IngressLoadBalancerStatus: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: IngressClassSpec: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Ingress", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Controller", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Controller = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Parameters", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -4541,8 +5317,10 @@ func (m *IngressLoadBalancerStatus) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Ingress = append(m.Ingress, IngressLoadBalancerIngress{}) - if err := m.Ingress[len(m.Ingress)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if m.Parameters == nil { + m.Parameters = &IngressClassParametersReference{} + } + if err := m.Parameters.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -4567,7 +5345,7 @@ func (m *IngressLoadBalancerStatus) Unmarshal(dAtA []byte) error { } return nil } -func (m *IngressPortStatus) Unmarshal(dAtA []byte) error { +func (m *IngressList) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4590,36 +5368,17 @@ func (m *IngressPortStatus) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: IngressPortStatus: wiretype end group for non-group") + return fmt.Errorf("proto: IngressList: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: IngressPortStatus: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: IngressList: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Port", wireType) - } - m.Port = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Port |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Protocol", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -4629,29 +5388,30 @@ func (m *IngressPortStatus) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.Protocol = k8s_io_api_core_v1.Protocol(dAtA[iNdEx:postIndex]) + if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 3: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -4661,24 +5421,25 @@ func (m *IngressPortStatus) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - s := string(dAtA[iNdEx:postIndex]) - m.Error = &s + m.Items = append(m.Items, Ingress{}) + if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -4701,7 +5462,7 @@ func (m *IngressPortStatus) Unmarshal(dAtA []byte) error { } return nil } -func (m *IngressRule) Unmarshal(dAtA []byte) error { +func (m *IngressLoadBalancerIngress) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4724,15 +5485,15 @@ func (m *IngressRule) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: IngressRule: wiretype end group for non-group") + return fmt.Errorf("proto: IngressLoadBalancerIngress: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: IngressRule: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: IngressLoadBalancerIngress: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Host", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field IP", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -4760,11 +5521,43 @@ func (m *IngressRule) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Host = string(dAtA[iNdEx:postIndex]) + m.IP = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field IngressRuleValue", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Hostname", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Hostname = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Ports", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -4791,7 +5584,8 @@ func (m *IngressRule) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.IngressRuleValue.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Ports = append(m.Ports, IngressPortStatus{}) + if err := m.Ports[len(m.Ports)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -4816,7 +5610,7 @@ func (m *IngressRule) Unmarshal(dAtA []byte) error { } return nil } -func (m *IngressRuleValue) Unmarshal(dAtA []byte) error { +func (m *IngressLoadBalancerStatus) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4839,15 +5633,15 @@ func (m *IngressRuleValue) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: IngressRuleValue: wiretype end group for non-group") + return fmt.Errorf("proto: IngressLoadBalancerStatus: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: IngressRuleValue: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: IngressLoadBalancerStatus: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field HTTP", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Ingress", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -4874,10 +5668,8 @@ func (m *IngressRuleValue) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.HTTP == nil { - m.HTTP = &HTTPIngressRuleValue{} - } - if err := m.HTTP.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Ingress = append(m.Ingress, IngressLoadBalancerIngress{}) + if err := m.Ingress[len(m.Ingress)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -4902,7 +5694,7 @@ func (m *IngressRuleValue) Unmarshal(dAtA []byte) error { } return nil } -func (m *IngressServiceBackend) Unmarshal(dAtA []byte) error { +func (m *IngressPortStatus) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4925,15 +5717,34 @@ func (m *IngressServiceBackend) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: IngressServiceBackend: wiretype end group for non-group") + return fmt.Errorf("proto: IngressPortStatus: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: IngressServiceBackend: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: IngressPortStatus: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Port", wireType) + } + m.Port = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Port |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Protocol", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -4961,13 +5772,13 @@ func (m *IngressServiceBackend) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Name = string(dAtA[iNdEx:postIndex]) + m.Protocol = k8s_io_api_core_v1.Protocol(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 2: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Port", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -4977,24 +5788,24 @@ func (m *IngressServiceBackend) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Port.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + s := string(dAtA[iNdEx:postIndex]) + m.Error = &s iNdEx = postIndex default: iNdEx = preIndex @@ -5017,7 +5828,7 @@ func (m *IngressServiceBackend) Unmarshal(dAtA []byte) error { } return nil } -func (m *IngressSpec) Unmarshal(dAtA []byte) error { +func (m *IngressRule) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -5040,17 +5851,17 @@ func (m *IngressSpec) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: IngressSpec: wiretype end group for non-group") + return fmt.Errorf("proto: IngressRule: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: IngressSpec: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: IngressRule: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DefaultBackend", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Host", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -5060,65 +5871,27 @@ func (m *IngressSpec) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - if m.DefaultBackend == nil { - m.DefaultBackend = &IngressBackend{} - } - if err := m.DefaultBackend.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Host = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TLS", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.TLS = append(m.TLS, IngressTLS{}) - if err := m.TLS[len(m.TLS)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Rules", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field IngressRuleValue", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -5145,44 +5918,10 @@ func (m *IngressSpec) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Rules = append(m.Rules, IngressRule{}) - if err := m.Rules[len(m.Rules)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.IngressRuleValue.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field IngressClassName", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(dAtA[iNdEx:postIndex]) - m.IngressClassName = &s - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -5204,7 +5943,7 @@ func (m *IngressSpec) Unmarshal(dAtA []byte) error { } return nil } -func (m *IngressStatus) Unmarshal(dAtA []byte) error { +func (m *IngressRuleValue) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -5227,15 +5966,15 @@ func (m *IngressStatus) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: IngressStatus: wiretype end group for non-group") + return fmt.Errorf("proto: IngressRuleValue: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: IngressStatus: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: IngressRuleValue: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field LoadBalancer", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field HTTP", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -5262,7 +6001,10 @@ func (m *IngressStatus) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.LoadBalancer.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if m.HTTP == nil { + m.HTTP = &HTTPIngressRuleValue{} + } + if err := m.HTTP.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -5287,7 +6029,7 @@ func (m *IngressStatus) Unmarshal(dAtA []byte) error { } return nil } -func (m *IngressTLS) Unmarshal(dAtA []byte) error { +func (m *IngressServiceBackend) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -5310,15 +6052,15 @@ func (m *IngressTLS) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: IngressTLS: wiretype end group for non-group") + return fmt.Errorf("proto: IngressServiceBackend: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: IngressTLS: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: IngressServiceBackend: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Hosts", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -5346,13 +6088,13 @@ func (m *IngressTLS) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Hosts = append(m.Hosts, string(dAtA[iNdEx:postIndex])) + m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SecretName", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Port", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -5362,23 +6104,24 @@ func (m *IngressTLS) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.SecretName = string(dAtA[iNdEx:postIndex]) + if err := m.Port.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -5401,7 +6144,7 @@ func (m *IngressTLS) Unmarshal(dAtA []byte) error { } return nil } -func (m *NetworkPolicy) Unmarshal(dAtA []byte) error { +func (m *IngressSpec) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -5424,15 +6167,15 @@ func (m *NetworkPolicy) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: NetworkPolicy: wiretype end group for non-group") + return fmt.Errorf("proto: IngressSpec: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: NetworkPolicy: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: IngressSpec: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field DefaultBackend", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -5459,13 +6202,16 @@ func (m *NetworkPolicy) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if m.DefaultBackend == nil { + m.DefaultBackend = &IngressBackend{} + } + if err := m.DefaultBackend.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field TLS", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -5492,63 +6238,14 @@ func (m *NetworkPolicy) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.TLS = append(m.TLS, IngressTLS{}) + if err := m.TLS[len(m.TLS)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *NetworkPolicyEgressRule) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: NetworkPolicyEgressRule: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: NetworkPolicyEgressRule: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Ports", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Rules", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -5575,16 +6272,99 @@ func (m *NetworkPolicyEgressRule) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Ports = append(m.Ports, NetworkPolicyPort{}) - if err := m.Ports[len(m.Ports)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Rules = append(m.Rules, IngressRule{}) + if err := m.Rules[len(m.Rules)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 2: + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field To", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field IngressClassName", wireType) } - var msglen int + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.IngressClassName = &s + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *IngressStatus) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: IngressStatus: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: IngressStatus: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field LoadBalancer", wireType) + } + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -5609,8 +6389,7 @@ func (m *NetworkPolicyEgressRule) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.To = append(m.To, NetworkPolicyPeer{}) - if err := m.To[len(m.To)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.LoadBalancer.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -5635,7 +6414,7 @@ func (m *NetworkPolicyEgressRule) Unmarshal(dAtA []byte) error { } return nil } -func (m *NetworkPolicyIngressRule) Unmarshal(dAtA []byte) error { +func (m *IngressTLS) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -5658,15 +6437,129 @@ func (m *NetworkPolicyIngressRule) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: NetworkPolicyIngressRule: wiretype end group for non-group") + return fmt.Errorf("proto: IngressTLS: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: NetworkPolicyIngressRule: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: IngressTLS: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Ports", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Hosts", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Hosts = append(m.Hosts, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SecretName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SecretName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *NetworkPolicy) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NetworkPolicy: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NetworkPolicy: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -5693,14 +6586,13 @@ func (m *NetworkPolicyIngressRule) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Ports = append(m.Ports, NetworkPolicyPort{}) - if err := m.Ports[len(m.Ports)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field From", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -5727,10 +6619,1020 @@ func (m *NetworkPolicyIngressRule) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.From = append(m.From, NetworkPolicyPeer{}) - if err := m.From[len(m.From)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { return err } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *NetworkPolicyEgressRule) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NetworkPolicyEgressRule: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NetworkPolicyEgressRule: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Ports", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Ports = append(m.Ports, NetworkPolicyPort{}) + if err := m.Ports[len(m.Ports)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field To", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.To = append(m.To, NetworkPolicyPeer{}) + if err := m.To[len(m.To)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *NetworkPolicyIngressRule) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NetworkPolicyIngressRule: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NetworkPolicyIngressRule: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Ports", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Ports = append(m.Ports, NetworkPolicyPort{}) + if err := m.Ports[len(m.Ports)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field From", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.From = append(m.From, NetworkPolicyPeer{}) + if err := m.From[len(m.From)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *NetworkPolicyList) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NetworkPolicyList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NetworkPolicyList: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Items = append(m.Items, NetworkPolicy{}) + if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *NetworkPolicyPeer) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NetworkPolicyPeer: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NetworkPolicyPeer: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PodSelector", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.PodSelector == nil { + m.PodSelector = &v1.LabelSelector{} + } + if err := m.PodSelector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NamespaceSelector", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.NamespaceSelector == nil { + m.NamespaceSelector = &v1.LabelSelector{} + } + if err := m.NamespaceSelector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field IPBlock", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.IPBlock == nil { + m.IPBlock = &IPBlock{} + } + if err := m.IPBlock.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *NetworkPolicyPort) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NetworkPolicyPort: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NetworkPolicyPort: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Protocol", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := k8s_io_api_core_v1.Protocol(dAtA[iNdEx:postIndex]) + m.Protocol = &s + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Port", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Port == nil { + m.Port = &intstr.IntOrString{} + } + if err := m.Port.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field EndPort", wireType) + } + var v int32 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.EndPort = &v + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *NetworkPolicySpec) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NetworkPolicySpec: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NetworkPolicySpec: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PodSelector", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.PodSelector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Ingress", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Ingress = append(m.Ingress, NetworkPolicyIngressRule{}) + if err := m.Ingress[len(m.Ingress)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Egress", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Egress = append(m.Egress, NetworkPolicyEgressRule{}) + if err := m.Egress[len(m.Egress)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PolicyTypes", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PolicyTypes = append(m.PolicyTypes, PolicyType(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ParentReference) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ParentReference: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ParentReference: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Group", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Group = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Resource", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Resource = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Namespace", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Namespace = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -5753,7 +7655,7 @@ func (m *NetworkPolicyIngressRule) Unmarshal(dAtA []byte) error { } return nil } -func (m *NetworkPolicyList) Unmarshal(dAtA []byte) error { +func (m *ServiceBackendPort) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -5776,17 +7678,17 @@ func (m *NetworkPolicyList) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: NetworkPolicyList: wiretype end group for non-group") + return fmt.Errorf("proto: ServiceBackendPort: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: NetworkPolicyList: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ServiceBackendPort: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -5796,30 +7698,29 @@ func (m *NetworkPolicyList) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Number", wireType) } - var msglen int + m.Number = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -5829,26 +7730,11 @@ func (m *NetworkPolicyList) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + m.Number |= int32(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Items = append(m.Items, NetworkPolicy{}) - if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -5870,7 +7756,7 @@ func (m *NetworkPolicyList) Unmarshal(dAtA []byte) error { } return nil } -func (m *NetworkPolicyPeer) Unmarshal(dAtA []byte) error { +func (m *ServiceCIDR) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -5893,15 +7779,15 @@ func (m *NetworkPolicyPeer) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: NetworkPolicyPeer: wiretype end group for non-group") + return fmt.Errorf("proto: ServiceCIDR: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: NetworkPolicyPeer: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ServiceCIDR: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PodSelector", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -5928,16 +7814,13 @@ func (m *NetworkPolicyPeer) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.PodSelector == nil { - m.PodSelector = &v1.LabelSelector{} - } - if err := m.PodSelector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field NamespaceSelector", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -5964,16 +7847,13 @@ func (m *NetworkPolicyPeer) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.NamespaceSelector == nil { - m.NamespaceSelector = &v1.LabelSelector{} - } - if err := m.NamespaceSelector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field IPBlock", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -6000,10 +7880,7 @@ func (m *NetworkPolicyPeer) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.IPBlock == nil { - m.IPBlock = &IPBlock{} - } - if err := m.IPBlock.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Status.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -6028,7 +7905,7 @@ func (m *NetworkPolicyPeer) Unmarshal(dAtA []byte) error { } return nil } -func (m *NetworkPolicyPort) Unmarshal(dAtA []byte) error { +func (m *ServiceCIDRList) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -6051,17 +7928,17 @@ func (m *NetworkPolicyPort) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: NetworkPolicyPort: wiretype end group for non-group") + return fmt.Errorf("proto: ServiceCIDRList: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: NetworkPolicyPort: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ServiceCIDRList: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Protocol", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -6071,28 +7948,28 @@ func (m *NetworkPolicyPort) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - s := k8s_io_api_core_v1.Protocol(dAtA[iNdEx:postIndex]) - m.Protocol = &s + if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Port", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -6119,33 +7996,11 @@ func (m *NetworkPolicyPort) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Port == nil { - m.Port = &intstr.IntOrString{} - } - if err := m.Port.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Items = append(m.Items, ServiceCIDR{}) + if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field EndPort", wireType) - } - var v int32 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.EndPort = &v default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -6167,7 +8022,7 @@ func (m *NetworkPolicyPort) Unmarshal(dAtA []byte) error { } return nil } -func (m *NetworkPolicySpec) Unmarshal(dAtA []byte) error { +func (m *ServiceCIDRSpec) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -6190,116 +8045,15 @@ func (m *NetworkPolicySpec) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: NetworkPolicySpec: wiretype end group for non-group") + return fmt.Errorf("proto: ServiceCIDRSpec: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: NetworkPolicySpec: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ServiceCIDRSpec: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PodSelector", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.PodSelector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Ingress", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Ingress = append(m.Ingress, NetworkPolicyIngressRule{}) - if err := m.Ingress[len(m.Ingress)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Egress", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Egress = append(m.Egress, NetworkPolicyEgressRule{}) - if err := m.Egress[len(m.Egress)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PolicyTypes", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field CIDRs", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -6327,7 +8081,7 @@ func (m *NetworkPolicySpec) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.PolicyTypes = append(m.PolicyTypes, PolicyType(dAtA[iNdEx:postIndex])) + m.CIDRs = append(m.CIDRs, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex @@ -6350,7 +8104,7 @@ func (m *NetworkPolicySpec) Unmarshal(dAtA []byte) error { } return nil } -func (m *ServiceBackendPort) Unmarshal(dAtA []byte) error { +func (m *ServiceCIDRStatus) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -6373,17 +8127,17 @@ func (m *ServiceBackendPort) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ServiceBackendPort: wiretype end group for non-group") + return fmt.Errorf("proto: ServiceCIDRStatus: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ServiceBackendPort: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ServiceCIDRStatus: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Conditions", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -6393,43 +8147,26 @@ func (m *ServiceBackendPort) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Number", wireType) - } - m.Number = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Number |= int32(b&0x7F) << shift - if b < 0x80 { - break - } + m.Conditions = append(m.Conditions, v1.Condition{}) + if err := m.Conditions[len(m.Conditions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/go-controller/vendor/k8s.io/api/networking/v1/generated.proto b/go-controller/vendor/k8s.io/api/networking/v1/generated.proto index c72fdc8f37..e3e3e9215e 100644 --- a/go-controller/vendor/k8s.io/api/networking/v1/generated.proto +++ b/go-controller/vendor/k8s.io/api/networking/v1/generated.proto @@ -72,6 +72,44 @@ message HTTPIngressRuleValue { repeated HTTPIngressPath paths = 1; } +// IPAddress represents a single IP of a single IP Family. The object is designed to be used by APIs +// that operate on IP addresses. The object is used by the Service core API for allocation of IP addresses. +// An IP address can be represented in different formats, to guarantee the uniqueness of the IP, +// the name of the object is the IP address in canonical format, four decimal digits separated +// by dots suppressing leading zeros for IPv4 and the representation defined by RFC 5952 for IPv6. +// Valid: 192.168.1.5 or 2001:db8::1 or 2001:db8:aaaa:bbbb:cccc:dddd:eeee:1 +// Invalid: 10.01.2.3 or 2001:db8:0:0:0::1 +message IPAddress { + // Standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; + + // spec is the desired state of the IPAddress. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + // +optional + optional IPAddressSpec spec = 2; +} + +// IPAddressList contains a list of IPAddress. +message IPAddressList { + // Standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; + + // items is the list of IPAddresses. + repeated IPAddress items = 2; +} + +// IPAddressSpec describe the attributes in an IP Address. +message IPAddressSpec { + // ParentRef references the resource that an IPAddress is attached to. + // An IPAddress must reference a parent object. + // +required + optional ParentReference parentRef = 1; +} + // IPBlock describes a particular CIDR (Ex. "192.168.1.0/24","2001:db8::/64") that is allowed // to the pods matched by a NetworkPolicySpec's podSelector. The except entry describes CIDRs // that should not be included within this rule. @@ -540,6 +578,25 @@ message NetworkPolicySpec { repeated string policyTypes = 4; } +// ParentReference describes a reference to a parent object. +message ParentReference { + // Group is the group of the object being referenced. + // +optional + optional string group = 1; + + // Resource is the resource of the object being referenced. + // +required + optional string resource = 2; + + // Namespace is the namespace of the object being referenced. + // +optional + optional string namespace = 3; + + // Name is the name of the object being referenced. + // +required + optional string name = 4; +} + // ServiceBackendPort is the service port being referenced. // +structType=atomic message ServiceBackendPort { @@ -554,3 +611,55 @@ message ServiceBackendPort { optional int32 number = 2; } +// ServiceCIDR defines a range of IP addresses using CIDR format (e.g. 192.168.0.0/24 or 2001:db2::/64). +// This range is used to allocate ClusterIPs to Service objects. +message ServiceCIDR { + // Standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; + + // spec is the desired state of the ServiceCIDR. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + // +optional + optional ServiceCIDRSpec spec = 2; + + // status represents the current state of the ServiceCIDR. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + // +optional + optional ServiceCIDRStatus status = 3; +} + +// ServiceCIDRList contains a list of ServiceCIDR objects. +message ServiceCIDRList { + // Standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; + + // items is the list of ServiceCIDRs. + repeated ServiceCIDR items = 2; +} + +// ServiceCIDRSpec define the CIDRs the user wants to use for allocating ClusterIPs for Services. +message ServiceCIDRSpec { + // CIDRs defines the IP blocks in CIDR notation (e.g. "192.168.0.0/24" or "2001:db8::/64") + // from which to assign service cluster IPs. Max of two CIDRs is allowed, one of each IP family. + // This field is immutable. + // +optional + // +listType=atomic + repeated string cidrs = 1; +} + +// ServiceCIDRStatus describes the current state of the ServiceCIDR. +message ServiceCIDRStatus { + // conditions holds an array of metav1.Condition that describe the state of the ServiceCIDR. + // Current service state + // +optional + // +patchMergeKey=type + // +patchStrategy=merge + // +listType=map + // +listMapKey=type + repeated .k8s.io.apimachinery.pkg.apis.meta.v1.Condition conditions = 1; +} + diff --git a/go-controller/vendor/k8s.io/api/networking/v1/register.go b/go-controller/vendor/k8s.io/api/networking/v1/register.go index a200d54370..b9bdcb78c9 100644 --- a/go-controller/vendor/k8s.io/api/networking/v1/register.go +++ b/go-controller/vendor/k8s.io/api/networking/v1/register.go @@ -50,6 +50,10 @@ func addKnownTypes(scheme *runtime.Scheme) error { &IngressClassList{}, &NetworkPolicy{}, &NetworkPolicyList{}, + &IPAddress{}, + &IPAddressList{}, + &ServiceCIDR{}, + &ServiceCIDRList{}, ) metav1.AddToGroupVersion(scheme, SchemeGroupVersion) diff --git a/go-controller/vendor/k8s.io/api/networking/v1/types.go b/go-controller/vendor/k8s.io/api/networking/v1/types.go index d75e27558d..216647ceeb 100644 --- a/go-controller/vendor/k8s.io/api/networking/v1/types.go +++ b/go-controller/vendor/k8s.io/api/networking/v1/types.go @@ -635,3 +635,133 @@ type IngressClassList struct { // items is the list of IngressClasses. Items []IngressClass `json:"items" protobuf:"bytes,2,rep,name=items"` } + +// +genclient +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.33 + +// IPAddress represents a single IP of a single IP Family. The object is designed to be used by APIs +// that operate on IP addresses. The object is used by the Service core API for allocation of IP addresses. +// An IP address can be represented in different formats, to guarantee the uniqueness of the IP, +// the name of the object is the IP address in canonical format, four decimal digits separated +// by dots suppressing leading zeros for IPv4 and the representation defined by RFC 5952 for IPv6. +// Valid: 192.168.1.5 or 2001:db8::1 or 2001:db8:aaaa:bbbb:cccc:dddd:eeee:1 +// Invalid: 10.01.2.3 or 2001:db8:0:0:0::1 +type IPAddress struct { + metav1.TypeMeta `json:",inline"` + // Standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + // spec is the desired state of the IPAddress. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + // +optional + Spec IPAddressSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` +} + +// IPAddressSpec describe the attributes in an IP Address. +type IPAddressSpec struct { + // ParentRef references the resource that an IPAddress is attached to. + // An IPAddress must reference a parent object. + // +required + ParentRef *ParentReference `json:"parentRef,omitempty" protobuf:"bytes,1,opt,name=parentRef"` +} + +// ParentReference describes a reference to a parent object. +type ParentReference struct { + // Group is the group of the object being referenced. + // +optional + Group string `json:"group,omitempty" protobuf:"bytes,1,opt,name=group"` + // Resource is the resource of the object being referenced. + // +required + Resource string `json:"resource,omitempty" protobuf:"bytes,2,opt,name=resource"` + // Namespace is the namespace of the object being referenced. + // +optional + Namespace string `json:"namespace,omitempty" protobuf:"bytes,3,opt,name=namespace"` + // Name is the name of the object being referenced. + // +required + Name string `json:"name,omitempty" protobuf:"bytes,4,opt,name=name"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.33 + +// IPAddressList contains a list of IPAddress. +type IPAddressList struct { + metav1.TypeMeta `json:",inline"` + // Standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + // items is the list of IPAddresses. + Items []IPAddress `json:"items" protobuf:"bytes,2,rep,name=items"` +} + +// +genclient +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.33 + +// ServiceCIDR defines a range of IP addresses using CIDR format (e.g. 192.168.0.0/24 or 2001:db2::/64). +// This range is used to allocate ClusterIPs to Service objects. +type ServiceCIDR struct { + metav1.TypeMeta `json:",inline"` + // Standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + // spec is the desired state of the ServiceCIDR. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + // +optional + Spec ServiceCIDRSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"` + // status represents the current state of the ServiceCIDR. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + // +optional + Status ServiceCIDRStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"` +} + +// ServiceCIDRSpec define the CIDRs the user wants to use for allocating ClusterIPs for Services. +type ServiceCIDRSpec struct { + // CIDRs defines the IP blocks in CIDR notation (e.g. "192.168.0.0/24" or "2001:db8::/64") + // from which to assign service cluster IPs. Max of two CIDRs is allowed, one of each IP family. + // This field is immutable. + // +optional + // +listType=atomic + CIDRs []string `json:"cidrs,omitempty" protobuf:"bytes,1,opt,name=cidrs"` +} + +const ( + // ServiceCIDRConditionReady represents status of a ServiceCIDR that is ready to be used by the + // apiserver to allocate ClusterIPs for Services. + ServiceCIDRConditionReady = "Ready" + // ServiceCIDRReasonTerminating represents a reason where a ServiceCIDR is not ready because it is + // being deleted. + ServiceCIDRReasonTerminating = "Terminating" +) + +// ServiceCIDRStatus describes the current state of the ServiceCIDR. +type ServiceCIDRStatus struct { + // conditions holds an array of metav1.Condition that describe the state of the ServiceCIDR. + // Current service state + // +optional + // +patchMergeKey=type + // +patchStrategy=merge + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.33 + +// ServiceCIDRList contains a list of ServiceCIDR objects. +type ServiceCIDRList struct { + metav1.TypeMeta `json:",inline"` + // Standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + // items is the list of ServiceCIDRs. + Items []ServiceCIDR `json:"items" protobuf:"bytes,2,rep,name=items"` +} diff --git a/go-controller/vendor/k8s.io/api/networking/v1/types_swagger_doc_generated.go b/go-controller/vendor/k8s.io/api/networking/v1/types_swagger_doc_generated.go index ff080540d3..0e294848ba 100644 --- a/go-controller/vendor/k8s.io/api/networking/v1/types_swagger_doc_generated.go +++ b/go-controller/vendor/k8s.io/api/networking/v1/types_swagger_doc_generated.go @@ -47,6 +47,35 @@ func (HTTPIngressRuleValue) SwaggerDoc() map[string]string { return map_HTTPIngressRuleValue } +var map_IPAddress = map[string]string{ + "": "IPAddress represents a single IP of a single IP Family. The object is designed to be used by APIs that operate on IP addresses. The object is used by the Service core API for allocation of IP addresses. An IP address can be represented in different formats, to guarantee the uniqueness of the IP, the name of the object is the IP address in canonical format, four decimal digits separated by dots suppressing leading zeros for IPv4 and the representation defined by RFC 5952 for IPv6. Valid: 192.168.1.5 or 2001:db8::1 or 2001:db8:aaaa:bbbb:cccc:dddd:eeee:1 Invalid: 10.01.2.3 or 2001:db8:0:0:0::1", + "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "spec": "spec is the desired state of the IPAddress. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", +} + +func (IPAddress) SwaggerDoc() map[string]string { + return map_IPAddress +} + +var map_IPAddressList = map[string]string{ + "": "IPAddressList contains a list of IPAddress.", + "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "items": "items is the list of IPAddresses.", +} + +func (IPAddressList) SwaggerDoc() map[string]string { + return map_IPAddressList +} + +var map_IPAddressSpec = map[string]string{ + "": "IPAddressSpec describe the attributes in an IP Address.", + "parentRef": "ParentRef references the resource that an IPAddress is attached to. An IPAddress must reference a parent object.", +} + +func (IPAddressSpec) SwaggerDoc() map[string]string { + return map_IPAddressSpec +} + var map_IPBlock = map[string]string{ "": "IPBlock describes a particular CIDR (Ex. \"192.168.1.0/24\",\"2001:db8::/64\") that is allowed to the pods matched by a NetworkPolicySpec's podSelector. The except entry describes CIDRs that should not be included within this rule.", "cidr": "cidr is a string representing the IPBlock Valid examples are \"192.168.1.0/24\" or \"2001:db8::/64\"", @@ -294,6 +323,18 @@ func (NetworkPolicySpec) SwaggerDoc() map[string]string { return map_NetworkPolicySpec } +var map_ParentReference = map[string]string{ + "": "ParentReference describes a reference to a parent object.", + "group": "Group is the group of the object being referenced.", + "resource": "Resource is the resource of the object being referenced.", + "namespace": "Namespace is the namespace of the object being referenced.", + "name": "Name is the name of the object being referenced.", +} + +func (ParentReference) SwaggerDoc() map[string]string { + return map_ParentReference +} + var map_ServiceBackendPort = map[string]string{ "": "ServiceBackendPort is the service port being referenced.", "name": "name is the name of the port on the Service. This is a mutually exclusive setting with \"Number\".", @@ -304,4 +345,43 @@ func (ServiceBackendPort) SwaggerDoc() map[string]string { return map_ServiceBackendPort } +var map_ServiceCIDR = map[string]string{ + "": "ServiceCIDR defines a range of IP addresses using CIDR format (e.g. 192.168.0.0/24 or 2001:db2::/64). This range is used to allocate ClusterIPs to Service objects.", + "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "spec": "spec is the desired state of the ServiceCIDR. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", + "status": "status represents the current state of the ServiceCIDR. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", +} + +func (ServiceCIDR) SwaggerDoc() map[string]string { + return map_ServiceCIDR +} + +var map_ServiceCIDRList = map[string]string{ + "": "ServiceCIDRList contains a list of ServiceCIDR objects.", + "metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", + "items": "items is the list of ServiceCIDRs.", +} + +func (ServiceCIDRList) SwaggerDoc() map[string]string { + return map_ServiceCIDRList +} + +var map_ServiceCIDRSpec = map[string]string{ + "": "ServiceCIDRSpec define the CIDRs the user wants to use for allocating ClusterIPs for Services.", + "cidrs": "CIDRs defines the IP blocks in CIDR notation (e.g. \"192.168.0.0/24\" or \"2001:db8::/64\") from which to assign service cluster IPs. Max of two CIDRs is allowed, one of each IP family. This field is immutable.", +} + +func (ServiceCIDRSpec) SwaggerDoc() map[string]string { + return map_ServiceCIDRSpec +} + +var map_ServiceCIDRStatus = map[string]string{ + "": "ServiceCIDRStatus describes the current state of the ServiceCIDR.", + "conditions": "conditions holds an array of metav1.Condition that describe the state of the ServiceCIDR. Current service state", +} + +func (ServiceCIDRStatus) SwaggerDoc() map[string]string { + return map_ServiceCIDRStatus +} + // AUTO-GENERATED FUNCTIONS END HERE diff --git a/go-controller/vendor/k8s.io/api/networking/v1/well_known_labels.go b/go-controller/vendor/k8s.io/api/networking/v1/well_known_labels.go new file mode 100644 index 0000000000..28e2e8f3f6 --- /dev/null +++ b/go-controller/vendor/k8s.io/api/networking/v1/well_known_labels.go @@ -0,0 +1,33 @@ +/* +Copyright 2023 The Kubernetes Authors. + +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 v1 + +const ( + + // TODO: Use IPFamily as field with a field selector,And the value is set based on + // the name at create time and immutable. + // LabelIPAddressFamily is used to indicate the IP family of a Kubernetes IPAddress. + // This label simplify dual-stack client operations allowing to obtain the list of + // IP addresses filtered by family. + LabelIPAddressFamily = "ipaddress.kubernetes.io/ip-family" + // LabelManagedBy is used to indicate the controller or entity that manages + // an IPAddress. This label aims to enable different IPAddress + // objects to be managed by different controllers or entities within the + // same cluster. It is highly recommended to configure this label for all + // IPAddress objects. + LabelManagedBy = "ipaddress.kubernetes.io/managed-by" +) diff --git a/go-controller/vendor/k8s.io/api/networking/v1/zz_generated.deepcopy.go b/go-controller/vendor/k8s.io/api/networking/v1/zz_generated.deepcopy.go index 540873833f..9ce6435a46 100644 --- a/go-controller/vendor/k8s.io/api/networking/v1/zz_generated.deepcopy.go +++ b/go-controller/vendor/k8s.io/api/networking/v1/zz_generated.deepcopy.go @@ -73,6 +73,87 @@ func (in *HTTPIngressRuleValue) DeepCopy() *HTTPIngressRuleValue { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IPAddress) DeepCopyInto(out *IPAddress) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IPAddress. +func (in *IPAddress) DeepCopy() *IPAddress { + if in == nil { + return nil + } + out := new(IPAddress) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *IPAddress) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IPAddressList) DeepCopyInto(out *IPAddressList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]IPAddress, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IPAddressList. +func (in *IPAddressList) DeepCopy() *IPAddressList { + if in == nil { + return nil + } + out := new(IPAddressList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *IPAddressList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IPAddressSpec) DeepCopyInto(out *IPAddressSpec) { + *out = *in + if in.ParentRef != nil { + in, out := &in.ParentRef, &out.ParentRef + *out = new(ParentReference) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IPAddressSpec. +func (in *IPAddressSpec) DeepCopy() *IPAddressSpec { + if in == nil { + return nil + } + out := new(IPAddressSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *IPBlock) DeepCopyInto(out *IPBlock) { *out = *in @@ -711,6 +792,22 @@ func (in *NetworkPolicySpec) DeepCopy() *NetworkPolicySpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ParentReference) DeepCopyInto(out *ParentReference) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ParentReference. +func (in *ParentReference) DeepCopy() *ParentReference { + if in == nil { + return nil + } + out := new(ParentReference) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ServiceBackendPort) DeepCopyInto(out *ServiceBackendPort) { *out = *in @@ -726,3 +823,108 @@ func (in *ServiceBackendPort) DeepCopy() *ServiceBackendPort { in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceCIDR) DeepCopyInto(out *ServiceCIDR) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceCIDR. +func (in *ServiceCIDR) DeepCopy() *ServiceCIDR { + if in == nil { + return nil + } + out := new(ServiceCIDR) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ServiceCIDR) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceCIDRList) DeepCopyInto(out *ServiceCIDRList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ServiceCIDR, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceCIDRList. +func (in *ServiceCIDRList) DeepCopy() *ServiceCIDRList { + if in == nil { + return nil + } + out := new(ServiceCIDRList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ServiceCIDRList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceCIDRSpec) DeepCopyInto(out *ServiceCIDRSpec) { + *out = *in + if in.CIDRs != nil { + in, out := &in.CIDRs, &out.CIDRs + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceCIDRSpec. +func (in *ServiceCIDRSpec) DeepCopy() *ServiceCIDRSpec { + if in == nil { + return nil + } + out := new(ServiceCIDRSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceCIDRStatus) DeepCopyInto(out *ServiceCIDRStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]metav1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceCIDRStatus. +func (in *ServiceCIDRStatus) DeepCopy() *ServiceCIDRStatus { + if in == nil { + return nil + } + out := new(ServiceCIDRStatus) + in.DeepCopyInto(out) + return out +} diff --git a/go-controller/vendor/k8s.io/api/networking/v1/zz_generated.prerelease-lifecycle.go b/go-controller/vendor/k8s.io/api/networking/v1/zz_generated.prerelease-lifecycle.go index 21e8c671a5..6894d8c539 100644 --- a/go-controller/vendor/k8s.io/api/networking/v1/zz_generated.prerelease-lifecycle.go +++ b/go-controller/vendor/k8s.io/api/networking/v1/zz_generated.prerelease-lifecycle.go @@ -21,6 +21,18 @@ limitations under the License. package v1 +// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. +func (in *IPAddress) APILifecycleIntroduced() (major, minor int) { + return 1, 33 +} + +// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. +func (in *IPAddressList) APILifecycleIntroduced() (major, minor int) { + return 1, 33 +} + // APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. // It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. func (in *Ingress) APILifecycleIntroduced() (major, minor int) { @@ -56,3 +68,15 @@ func (in *NetworkPolicy) APILifecycleIntroduced() (major, minor int) { func (in *NetworkPolicyList) APILifecycleIntroduced() (major, minor int) { return 1, 19 } + +// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. +func (in *ServiceCIDR) APILifecycleIntroduced() (major, minor int) { + return 1, 33 +} + +// APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. +// It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. +func (in *ServiceCIDRList) APILifecycleIntroduced() (major, minor int) { + return 1, 33 +} diff --git a/go-controller/vendor/k8s.io/api/networking/v1alpha1/doc.go b/go-controller/vendor/k8s.io/api/networking/v1alpha1/doc.go index 3827b0418f..55264ae707 100644 --- a/go-controller/vendor/k8s.io/api/networking/v1alpha1/doc.go +++ b/go-controller/vendor/k8s.io/api/networking/v1alpha1/doc.go @@ -20,4 +20,4 @@ limitations under the License. // +k8s:prerelease-lifecycle-gen=true // +groupName=networking.k8s.io -package v1alpha1 // import "k8s.io/api/networking/v1alpha1" +package v1alpha1 diff --git a/go-controller/vendor/k8s.io/api/networking/v1beta1/doc.go b/go-controller/vendor/k8s.io/api/networking/v1beta1/doc.go index fa6d01cea0..c5a03e04e8 100644 --- a/go-controller/vendor/k8s.io/api/networking/v1beta1/doc.go +++ b/go-controller/vendor/k8s.io/api/networking/v1beta1/doc.go @@ -20,4 +20,4 @@ limitations under the License. // +k8s:prerelease-lifecycle-gen=true // +groupName=networking.k8s.io -package v1beta1 // import "k8s.io/api/networking/v1beta1" +package v1beta1 diff --git a/go-controller/vendor/k8s.io/api/node/v1/doc.go b/go-controller/vendor/k8s.io/api/node/v1/doc.go index 57ca52445b..3239af7039 100644 --- a/go-controller/vendor/k8s.io/api/node/v1/doc.go +++ b/go-controller/vendor/k8s.io/api/node/v1/doc.go @@ -20,4 +20,4 @@ limitations under the License. // +k8s:prerelease-lifecycle-gen=true // +groupName=node.k8s.io -package v1 // import "k8s.io/api/node/v1" +package v1 diff --git a/go-controller/vendor/k8s.io/api/node/v1alpha1/doc.go b/go-controller/vendor/k8s.io/api/node/v1alpha1/doc.go index dfe99540b5..2f3d46ac20 100644 --- a/go-controller/vendor/k8s.io/api/node/v1alpha1/doc.go +++ b/go-controller/vendor/k8s.io/api/node/v1alpha1/doc.go @@ -20,4 +20,4 @@ limitations under the License. // +groupName=node.k8s.io -package v1alpha1 // import "k8s.io/api/node/v1alpha1" +package v1alpha1 diff --git a/go-controller/vendor/k8s.io/api/node/v1beta1/doc.go b/go-controller/vendor/k8s.io/api/node/v1beta1/doc.go index c76ba89c48..7b47c8df66 100644 --- a/go-controller/vendor/k8s.io/api/node/v1beta1/doc.go +++ b/go-controller/vendor/k8s.io/api/node/v1beta1/doc.go @@ -21,4 +21,4 @@ limitations under the License. // +groupName=node.k8s.io -package v1beta1 // import "k8s.io/api/node/v1beta1" +package v1beta1 diff --git a/go-controller/vendor/k8s.io/api/policy/v1/doc.go b/go-controller/vendor/k8s.io/api/policy/v1/doc.go index c51e02685a..ff47e7fd49 100644 --- a/go-controller/vendor/k8s.io/api/policy/v1/doc.go +++ b/go-controller/vendor/k8s.io/api/policy/v1/doc.go @@ -22,4 +22,4 @@ limitations under the License. // Package policy is for any kind of policy object. Suitable examples, even if // they aren't all here, are PodDisruptionBudget, // NetworkPolicy, etc. -package v1 // import "k8s.io/api/policy/v1" +package v1 diff --git a/go-controller/vendor/k8s.io/api/policy/v1/generated.proto b/go-controller/vendor/k8s.io/api/policy/v1/generated.proto index 57128e8112..9534890723 100644 --- a/go-controller/vendor/k8s.io/api/policy/v1/generated.proto +++ b/go-controller/vendor/k8s.io/api/policy/v1/generated.proto @@ -115,9 +115,6 @@ message PodDisruptionBudgetSpec { // Additional policies may be added in the future. // Clients making eviction decisions should disallow eviction of unhealthy pods // if they encounter an unrecognized policy in this field. - // - // This field is beta-level. The eviction API uses this field when - // the feature gate PDBUnhealthyPodEvictionPolicy is enabled (enabled by default). // +optional optional string unhealthyPodEvictionPolicy = 4; } diff --git a/go-controller/vendor/k8s.io/api/policy/v1/types.go b/go-controller/vendor/k8s.io/api/policy/v1/types.go index f05367ebe4..4e74367894 100644 --- a/go-controller/vendor/k8s.io/api/policy/v1/types.go +++ b/go-controller/vendor/k8s.io/api/policy/v1/types.go @@ -70,9 +70,6 @@ type PodDisruptionBudgetSpec struct { // Additional policies may be added in the future. // Clients making eviction decisions should disallow eviction of unhealthy pods // if they encounter an unrecognized policy in this field. - // - // This field is beta-level. The eviction API uses this field when - // the feature gate PDBUnhealthyPodEvictionPolicy is enabled (enabled by default). // +optional UnhealthyPodEvictionPolicy *UnhealthyPodEvictionPolicyType `json:"unhealthyPodEvictionPolicy,omitempty" protobuf:"bytes,4,opt,name=unhealthyPodEvictionPolicy"` } diff --git a/go-controller/vendor/k8s.io/api/policy/v1/types_swagger_doc_generated.go b/go-controller/vendor/k8s.io/api/policy/v1/types_swagger_doc_generated.go index 799b0794a9..9b2f5b9450 100644 --- a/go-controller/vendor/k8s.io/api/policy/v1/types_swagger_doc_generated.go +++ b/go-controller/vendor/k8s.io/api/policy/v1/types_swagger_doc_generated.go @@ -63,7 +63,7 @@ var map_PodDisruptionBudgetSpec = map[string]string{ "minAvailable": "An eviction is allowed if at least \"minAvailable\" pods selected by \"selector\" will still be available after the eviction, i.e. even in the absence of the evicted pod. So for example you can prevent all voluntary evictions by specifying \"100%\".", "selector": "Label query over pods whose evictions are managed by the disruption budget. A null selector will match no pods, while an empty ({}) selector will select all pods within the namespace.", "maxUnavailable": "An eviction is allowed if at most \"maxUnavailable\" pods selected by \"selector\" are unavailable after the eviction, i.e. even in absence of the evicted pod. For example, one can prevent all voluntary evictions by specifying 0. This is a mutually exclusive setting with \"minAvailable\".", - "unhealthyPodEvictionPolicy": "UnhealthyPodEvictionPolicy defines the criteria for when unhealthy pods should be considered for eviction. Current implementation considers healthy pods, as pods that have status.conditions item with type=\"Ready\",status=\"True\".\n\nValid policies are IfHealthyBudget and AlwaysAllow. If no policy is specified, the default behavior will be used, which corresponds to the IfHealthyBudget policy.\n\nIfHealthyBudget policy means that running pods (status.phase=\"Running\"), but not yet healthy can be evicted only if the guarded application is not disrupted (status.currentHealthy is at least equal to status.desiredHealthy). Healthy pods will be subject to the PDB for eviction.\n\nAlwaysAllow policy means that all running pods (status.phase=\"Running\"), but not yet healthy are considered disrupted and can be evicted regardless of whether the criteria in a PDB is met. This means perspective running pods of a disrupted application might not get a chance to become healthy. Healthy pods will be subject to the PDB for eviction.\n\nAdditional policies may be added in the future. Clients making eviction decisions should disallow eviction of unhealthy pods if they encounter an unrecognized policy in this field.\n\nThis field is beta-level. The eviction API uses this field when the feature gate PDBUnhealthyPodEvictionPolicy is enabled (enabled by default).", + "unhealthyPodEvictionPolicy": "UnhealthyPodEvictionPolicy defines the criteria for when unhealthy pods should be considered for eviction. Current implementation considers healthy pods, as pods that have status.conditions item with type=\"Ready\",status=\"True\".\n\nValid policies are IfHealthyBudget and AlwaysAllow. If no policy is specified, the default behavior will be used, which corresponds to the IfHealthyBudget policy.\n\nIfHealthyBudget policy means that running pods (status.phase=\"Running\"), but not yet healthy can be evicted only if the guarded application is not disrupted (status.currentHealthy is at least equal to status.desiredHealthy). Healthy pods will be subject to the PDB for eviction.\n\nAlwaysAllow policy means that all running pods (status.phase=\"Running\"), but not yet healthy are considered disrupted and can be evicted regardless of whether the criteria in a PDB is met. This means perspective running pods of a disrupted application might not get a chance to become healthy. Healthy pods will be subject to the PDB for eviction.\n\nAdditional policies may be added in the future. Clients making eviction decisions should disallow eviction of unhealthy pods if they encounter an unrecognized policy in this field.", } func (PodDisruptionBudgetSpec) SwaggerDoc() map[string]string { diff --git a/go-controller/vendor/k8s.io/api/policy/v1beta1/doc.go b/go-controller/vendor/k8s.io/api/policy/v1beta1/doc.go index 76da54b4c7..777106c600 100644 --- a/go-controller/vendor/k8s.io/api/policy/v1beta1/doc.go +++ b/go-controller/vendor/k8s.io/api/policy/v1beta1/doc.go @@ -22,4 +22,4 @@ limitations under the License. // Package policy is for any kind of policy object. Suitable examples, even if // they aren't all here, are PodDisruptionBudget, // NetworkPolicy, etc. -package v1beta1 // import "k8s.io/api/policy/v1beta1" +package v1beta1 diff --git a/go-controller/vendor/k8s.io/api/policy/v1beta1/generated.proto b/go-controller/vendor/k8s.io/api/policy/v1beta1/generated.proto index 91e33f2332..e0cbe00f1c 100644 --- a/go-controller/vendor/k8s.io/api/policy/v1beta1/generated.proto +++ b/go-controller/vendor/k8s.io/api/policy/v1beta1/generated.proto @@ -115,9 +115,6 @@ message PodDisruptionBudgetSpec { // Additional policies may be added in the future. // Clients making eviction decisions should disallow eviction of unhealthy pods // if they encounter an unrecognized policy in this field. - // - // This field is beta-level. The eviction API uses this field when - // the feature gate PDBUnhealthyPodEvictionPolicy is enabled (enabled by default). // +optional optional string unhealthyPodEvictionPolicy = 4; } diff --git a/go-controller/vendor/k8s.io/api/policy/v1beta1/types.go b/go-controller/vendor/k8s.io/api/policy/v1beta1/types.go index bc5f970d27..9bba454f94 100644 --- a/go-controller/vendor/k8s.io/api/policy/v1beta1/types.go +++ b/go-controller/vendor/k8s.io/api/policy/v1beta1/types.go @@ -67,9 +67,6 @@ type PodDisruptionBudgetSpec struct { // Additional policies may be added in the future. // Clients making eviction decisions should disallow eviction of unhealthy pods // if they encounter an unrecognized policy in this field. - // - // This field is beta-level. The eviction API uses this field when - // the feature gate PDBUnhealthyPodEvictionPolicy is enabled (enabled by default). // +optional UnhealthyPodEvictionPolicy *UnhealthyPodEvictionPolicyType `json:"unhealthyPodEvictionPolicy,omitempty" protobuf:"bytes,4,opt,name=unhealthyPodEvictionPolicy"` } diff --git a/go-controller/vendor/k8s.io/api/policy/v1beta1/types_swagger_doc_generated.go b/go-controller/vendor/k8s.io/api/policy/v1beta1/types_swagger_doc_generated.go index 4a79d75949..cffc9a548c 100644 --- a/go-controller/vendor/k8s.io/api/policy/v1beta1/types_swagger_doc_generated.go +++ b/go-controller/vendor/k8s.io/api/policy/v1beta1/types_swagger_doc_generated.go @@ -63,7 +63,7 @@ var map_PodDisruptionBudgetSpec = map[string]string{ "minAvailable": "An eviction is allowed if at least \"minAvailable\" pods selected by \"selector\" will still be available after the eviction, i.e. even in the absence of the evicted pod. So for example you can prevent all voluntary evictions by specifying \"100%\".", "selector": "Label query over pods whose evictions are managed by the disruption budget. A null selector selects no pods. An empty selector ({}) also selects no pods, which differs from standard behavior of selecting all pods. In policy/v1, an empty selector will select all pods in the namespace.", "maxUnavailable": "An eviction is allowed if at most \"maxUnavailable\" pods selected by \"selector\" are unavailable after the eviction, i.e. even in absence of the evicted pod. For example, one can prevent all voluntary evictions by specifying 0. This is a mutually exclusive setting with \"minAvailable\".", - "unhealthyPodEvictionPolicy": "UnhealthyPodEvictionPolicy defines the criteria for when unhealthy pods should be considered for eviction. Current implementation considers healthy pods, as pods that have status.conditions item with type=\"Ready\",status=\"True\".\n\nValid policies are IfHealthyBudget and AlwaysAllow. If no policy is specified, the default behavior will be used, which corresponds to the IfHealthyBudget policy.\n\nIfHealthyBudget policy means that running pods (status.phase=\"Running\"), but not yet healthy can be evicted only if the guarded application is not disrupted (status.currentHealthy is at least equal to status.desiredHealthy). Healthy pods will be subject to the PDB for eviction.\n\nAlwaysAllow policy means that all running pods (status.phase=\"Running\"), but not yet healthy are considered disrupted and can be evicted regardless of whether the criteria in a PDB is met. This means perspective running pods of a disrupted application might not get a chance to become healthy. Healthy pods will be subject to the PDB for eviction.\n\nAdditional policies may be added in the future. Clients making eviction decisions should disallow eviction of unhealthy pods if they encounter an unrecognized policy in this field.\n\nThis field is beta-level. The eviction API uses this field when the feature gate PDBUnhealthyPodEvictionPolicy is enabled (enabled by default).", + "unhealthyPodEvictionPolicy": "UnhealthyPodEvictionPolicy defines the criteria for when unhealthy pods should be considered for eviction. Current implementation considers healthy pods, as pods that have status.conditions item with type=\"Ready\",status=\"True\".\n\nValid policies are IfHealthyBudget and AlwaysAllow. If no policy is specified, the default behavior will be used, which corresponds to the IfHealthyBudget policy.\n\nIfHealthyBudget policy means that running pods (status.phase=\"Running\"), but not yet healthy can be evicted only if the guarded application is not disrupted (status.currentHealthy is at least equal to status.desiredHealthy). Healthy pods will be subject to the PDB for eviction.\n\nAlwaysAllow policy means that all running pods (status.phase=\"Running\"), but not yet healthy are considered disrupted and can be evicted regardless of whether the criteria in a PDB is met. This means perspective running pods of a disrupted application might not get a chance to become healthy. Healthy pods will be subject to the PDB for eviction.\n\nAdditional policies may be added in the future. Clients making eviction decisions should disallow eviction of unhealthy pods if they encounter an unrecognized policy in this field.", } func (PodDisruptionBudgetSpec) SwaggerDoc() map[string]string { diff --git a/go-controller/vendor/k8s.io/api/rbac/v1/doc.go b/go-controller/vendor/k8s.io/api/rbac/v1/doc.go index b0e4e5b5b5..408546274b 100644 --- a/go-controller/vendor/k8s.io/api/rbac/v1/doc.go +++ b/go-controller/vendor/k8s.io/api/rbac/v1/doc.go @@ -20,4 +20,4 @@ limitations under the License. // +k8s:prerelease-lifecycle-gen=true // +groupName=rbac.authorization.k8s.io -package v1 // import "k8s.io/api/rbac/v1" +package v1 diff --git a/go-controller/vendor/k8s.io/api/rbac/v1alpha1/doc.go b/go-controller/vendor/k8s.io/api/rbac/v1alpha1/doc.go index 918b8a337c..70d3c0e971 100644 --- a/go-controller/vendor/k8s.io/api/rbac/v1alpha1/doc.go +++ b/go-controller/vendor/k8s.io/api/rbac/v1alpha1/doc.go @@ -20,4 +20,4 @@ limitations under the License. // +groupName=rbac.authorization.k8s.io -package v1alpha1 // import "k8s.io/api/rbac/v1alpha1" +package v1alpha1 diff --git a/go-controller/vendor/k8s.io/api/rbac/v1beta1/doc.go b/go-controller/vendor/k8s.io/api/rbac/v1beta1/doc.go index 156f273e69..504a58d8bf 100644 --- a/go-controller/vendor/k8s.io/api/rbac/v1beta1/doc.go +++ b/go-controller/vendor/k8s.io/api/rbac/v1beta1/doc.go @@ -21,4 +21,4 @@ limitations under the License. // +groupName=rbac.authorization.k8s.io -package v1beta1 // import "k8s.io/api/rbac/v1beta1" +package v1beta1 diff --git a/go-controller/vendor/k8s.io/api/resource/v1alpha3/doc.go b/go-controller/vendor/k8s.io/api/resource/v1alpha3/doc.go index ffc21307d0..82e64f1d00 100644 --- a/go-controller/vendor/k8s.io/api/resource/v1alpha3/doc.go +++ b/go-controller/vendor/k8s.io/api/resource/v1alpha3/doc.go @@ -21,4 +21,4 @@ limitations under the License. // +groupName=resource.k8s.io // Package v1alpha3 is the v1alpha3 version of the resource API. -package v1alpha3 // import "k8s.io/api/resource/v1alpha3" +package v1alpha3 diff --git a/go-controller/vendor/k8s.io/api/resource/v1alpha3/generated.pb.go b/go-controller/vendor/k8s.io/api/resource/v1alpha3/generated.pb.go index 540f7b8184..716492fea4 100644 --- a/go-controller/vendor/k8s.io/api/resource/v1alpha3/generated.pb.go +++ b/go-controller/vendor/k8s.io/api/resource/v1alpha3/generated.pb.go @@ -29,6 +29,7 @@ import ( v11 "k8s.io/api/core/v1" resource "k8s.io/apimachinery/pkg/api/resource" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" math "math" math_bits "math/bits" @@ -161,10 +162,66 @@ func (m *CELDeviceSelector) XXX_DiscardUnknown() { var xxx_messageInfo_CELDeviceSelector proto.InternalMessageInfo +func (m *Counter) Reset() { *m = Counter{} } +func (*Counter) ProtoMessage() {} +func (*Counter) Descriptor() ([]byte, []int) { + return fileDescriptor_66649ee9bbcd89d2, []int{4} +} +func (m *Counter) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Counter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *Counter) XXX_Merge(src proto.Message) { + xxx_messageInfo_Counter.Merge(m, src) +} +func (m *Counter) XXX_Size() int { + return m.Size() +} +func (m *Counter) XXX_DiscardUnknown() { + xxx_messageInfo_Counter.DiscardUnknown(m) +} + +var xxx_messageInfo_Counter proto.InternalMessageInfo + +func (m *CounterSet) Reset() { *m = CounterSet{} } +func (*CounterSet) ProtoMessage() {} +func (*CounterSet) Descriptor() ([]byte, []int) { + return fileDescriptor_66649ee9bbcd89d2, []int{5} +} +func (m *CounterSet) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *CounterSet) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *CounterSet) XXX_Merge(src proto.Message) { + xxx_messageInfo_CounterSet.Merge(m, src) +} +func (m *CounterSet) XXX_Size() int { + return m.Size() +} +func (m *CounterSet) XXX_DiscardUnknown() { + xxx_messageInfo_CounterSet.DiscardUnknown(m) +} + +var xxx_messageInfo_CounterSet proto.InternalMessageInfo + func (m *Device) Reset() { *m = Device{} } func (*Device) ProtoMessage() {} func (*Device) Descriptor() ([]byte, []int) { - return fileDescriptor_66649ee9bbcd89d2, []int{4} + return fileDescriptor_66649ee9bbcd89d2, []int{6} } func (m *Device) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -192,7 +249,7 @@ var xxx_messageInfo_Device proto.InternalMessageInfo func (m *DeviceAllocationConfiguration) Reset() { *m = DeviceAllocationConfiguration{} } func (*DeviceAllocationConfiguration) ProtoMessage() {} func (*DeviceAllocationConfiguration) Descriptor() ([]byte, []int) { - return fileDescriptor_66649ee9bbcd89d2, []int{5} + return fileDescriptor_66649ee9bbcd89d2, []int{7} } func (m *DeviceAllocationConfiguration) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -220,7 +277,7 @@ var xxx_messageInfo_DeviceAllocationConfiguration proto.InternalMessageInfo func (m *DeviceAllocationResult) Reset() { *m = DeviceAllocationResult{} } func (*DeviceAllocationResult) ProtoMessage() {} func (*DeviceAllocationResult) Descriptor() ([]byte, []int) { - return fileDescriptor_66649ee9bbcd89d2, []int{6} + return fileDescriptor_66649ee9bbcd89d2, []int{8} } func (m *DeviceAllocationResult) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -248,7 +305,7 @@ var xxx_messageInfo_DeviceAllocationResult proto.InternalMessageInfo func (m *DeviceAttribute) Reset() { *m = DeviceAttribute{} } func (*DeviceAttribute) ProtoMessage() {} func (*DeviceAttribute) Descriptor() ([]byte, []int) { - return fileDescriptor_66649ee9bbcd89d2, []int{7} + return fileDescriptor_66649ee9bbcd89d2, []int{9} } func (m *DeviceAttribute) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -276,7 +333,7 @@ var xxx_messageInfo_DeviceAttribute proto.InternalMessageInfo func (m *DeviceClaim) Reset() { *m = DeviceClaim{} } func (*DeviceClaim) ProtoMessage() {} func (*DeviceClaim) Descriptor() ([]byte, []int) { - return fileDescriptor_66649ee9bbcd89d2, []int{8} + return fileDescriptor_66649ee9bbcd89d2, []int{10} } func (m *DeviceClaim) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -304,7 +361,7 @@ var xxx_messageInfo_DeviceClaim proto.InternalMessageInfo func (m *DeviceClaimConfiguration) Reset() { *m = DeviceClaimConfiguration{} } func (*DeviceClaimConfiguration) ProtoMessage() {} func (*DeviceClaimConfiguration) Descriptor() ([]byte, []int) { - return fileDescriptor_66649ee9bbcd89d2, []int{9} + return fileDescriptor_66649ee9bbcd89d2, []int{11} } func (m *DeviceClaimConfiguration) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -332,7 +389,7 @@ var xxx_messageInfo_DeviceClaimConfiguration proto.InternalMessageInfo func (m *DeviceClass) Reset() { *m = DeviceClass{} } func (*DeviceClass) ProtoMessage() {} func (*DeviceClass) Descriptor() ([]byte, []int) { - return fileDescriptor_66649ee9bbcd89d2, []int{10} + return fileDescriptor_66649ee9bbcd89d2, []int{12} } func (m *DeviceClass) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -360,7 +417,7 @@ var xxx_messageInfo_DeviceClass proto.InternalMessageInfo func (m *DeviceClassConfiguration) Reset() { *m = DeviceClassConfiguration{} } func (*DeviceClassConfiguration) ProtoMessage() {} func (*DeviceClassConfiguration) Descriptor() ([]byte, []int) { - return fileDescriptor_66649ee9bbcd89d2, []int{11} + return fileDescriptor_66649ee9bbcd89d2, []int{13} } func (m *DeviceClassConfiguration) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -388,7 +445,7 @@ var xxx_messageInfo_DeviceClassConfiguration proto.InternalMessageInfo func (m *DeviceClassList) Reset() { *m = DeviceClassList{} } func (*DeviceClassList) ProtoMessage() {} func (*DeviceClassList) Descriptor() ([]byte, []int) { - return fileDescriptor_66649ee9bbcd89d2, []int{12} + return fileDescriptor_66649ee9bbcd89d2, []int{14} } func (m *DeviceClassList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -416,7 +473,7 @@ var xxx_messageInfo_DeviceClassList proto.InternalMessageInfo func (m *DeviceClassSpec) Reset() { *m = DeviceClassSpec{} } func (*DeviceClassSpec) ProtoMessage() {} func (*DeviceClassSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_66649ee9bbcd89d2, []int{13} + return fileDescriptor_66649ee9bbcd89d2, []int{15} } func (m *DeviceClassSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -444,7 +501,7 @@ var xxx_messageInfo_DeviceClassSpec proto.InternalMessageInfo func (m *DeviceConfiguration) Reset() { *m = DeviceConfiguration{} } func (*DeviceConfiguration) ProtoMessage() {} func (*DeviceConfiguration) Descriptor() ([]byte, []int) { - return fileDescriptor_66649ee9bbcd89d2, []int{14} + return fileDescriptor_66649ee9bbcd89d2, []int{16} } func (m *DeviceConfiguration) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -472,7 +529,7 @@ var xxx_messageInfo_DeviceConfiguration proto.InternalMessageInfo func (m *DeviceConstraint) Reset() { *m = DeviceConstraint{} } func (*DeviceConstraint) ProtoMessage() {} func (*DeviceConstraint) Descriptor() ([]byte, []int) { - return fileDescriptor_66649ee9bbcd89d2, []int{15} + return fileDescriptor_66649ee9bbcd89d2, []int{17} } func (m *DeviceConstraint) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -497,10 +554,38 @@ func (m *DeviceConstraint) XXX_DiscardUnknown() { var xxx_messageInfo_DeviceConstraint proto.InternalMessageInfo +func (m *DeviceCounterConsumption) Reset() { *m = DeviceCounterConsumption{} } +func (*DeviceCounterConsumption) ProtoMessage() {} +func (*DeviceCounterConsumption) Descriptor() ([]byte, []int) { + return fileDescriptor_66649ee9bbcd89d2, []int{18} +} +func (m *DeviceCounterConsumption) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *DeviceCounterConsumption) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *DeviceCounterConsumption) XXX_Merge(src proto.Message) { + xxx_messageInfo_DeviceCounterConsumption.Merge(m, src) +} +func (m *DeviceCounterConsumption) XXX_Size() int { + return m.Size() +} +func (m *DeviceCounterConsumption) XXX_DiscardUnknown() { + xxx_messageInfo_DeviceCounterConsumption.DiscardUnknown(m) +} + +var xxx_messageInfo_DeviceCounterConsumption proto.InternalMessageInfo + func (m *DeviceRequest) Reset() { *m = DeviceRequest{} } func (*DeviceRequest) ProtoMessage() {} func (*DeviceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_66649ee9bbcd89d2, []int{16} + return fileDescriptor_66649ee9bbcd89d2, []int{19} } func (m *DeviceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -528,7 +613,7 @@ var xxx_messageInfo_DeviceRequest proto.InternalMessageInfo func (m *DeviceRequestAllocationResult) Reset() { *m = DeviceRequestAllocationResult{} } func (*DeviceRequestAllocationResult) ProtoMessage() {} func (*DeviceRequestAllocationResult) Descriptor() ([]byte, []int) { - return fileDescriptor_66649ee9bbcd89d2, []int{17} + return fileDescriptor_66649ee9bbcd89d2, []int{20} } func (m *DeviceRequestAllocationResult) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -556,7 +641,7 @@ var xxx_messageInfo_DeviceRequestAllocationResult proto.InternalMessageInfo func (m *DeviceSelector) Reset() { *m = DeviceSelector{} } func (*DeviceSelector) ProtoMessage() {} func (*DeviceSelector) Descriptor() ([]byte, []int) { - return fileDescriptor_66649ee9bbcd89d2, []int{18} + return fileDescriptor_66649ee9bbcd89d2, []int{21} } func (m *DeviceSelector) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -581,10 +666,206 @@ func (m *DeviceSelector) XXX_DiscardUnknown() { var xxx_messageInfo_DeviceSelector proto.InternalMessageInfo +func (m *DeviceSubRequest) Reset() { *m = DeviceSubRequest{} } +func (*DeviceSubRequest) ProtoMessage() {} +func (*DeviceSubRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_66649ee9bbcd89d2, []int{22} +} +func (m *DeviceSubRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *DeviceSubRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *DeviceSubRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_DeviceSubRequest.Merge(m, src) +} +func (m *DeviceSubRequest) XXX_Size() int { + return m.Size() +} +func (m *DeviceSubRequest) XXX_DiscardUnknown() { + xxx_messageInfo_DeviceSubRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_DeviceSubRequest proto.InternalMessageInfo + +func (m *DeviceTaint) Reset() { *m = DeviceTaint{} } +func (*DeviceTaint) ProtoMessage() {} +func (*DeviceTaint) Descriptor() ([]byte, []int) { + return fileDescriptor_66649ee9bbcd89d2, []int{23} +} +func (m *DeviceTaint) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *DeviceTaint) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *DeviceTaint) XXX_Merge(src proto.Message) { + xxx_messageInfo_DeviceTaint.Merge(m, src) +} +func (m *DeviceTaint) XXX_Size() int { + return m.Size() +} +func (m *DeviceTaint) XXX_DiscardUnknown() { + xxx_messageInfo_DeviceTaint.DiscardUnknown(m) +} + +var xxx_messageInfo_DeviceTaint proto.InternalMessageInfo + +func (m *DeviceTaintRule) Reset() { *m = DeviceTaintRule{} } +func (*DeviceTaintRule) ProtoMessage() {} +func (*DeviceTaintRule) Descriptor() ([]byte, []int) { + return fileDescriptor_66649ee9bbcd89d2, []int{24} +} +func (m *DeviceTaintRule) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *DeviceTaintRule) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *DeviceTaintRule) XXX_Merge(src proto.Message) { + xxx_messageInfo_DeviceTaintRule.Merge(m, src) +} +func (m *DeviceTaintRule) XXX_Size() int { + return m.Size() +} +func (m *DeviceTaintRule) XXX_DiscardUnknown() { + xxx_messageInfo_DeviceTaintRule.DiscardUnknown(m) +} + +var xxx_messageInfo_DeviceTaintRule proto.InternalMessageInfo + +func (m *DeviceTaintRuleList) Reset() { *m = DeviceTaintRuleList{} } +func (*DeviceTaintRuleList) ProtoMessage() {} +func (*DeviceTaintRuleList) Descriptor() ([]byte, []int) { + return fileDescriptor_66649ee9bbcd89d2, []int{25} +} +func (m *DeviceTaintRuleList) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *DeviceTaintRuleList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *DeviceTaintRuleList) XXX_Merge(src proto.Message) { + xxx_messageInfo_DeviceTaintRuleList.Merge(m, src) +} +func (m *DeviceTaintRuleList) XXX_Size() int { + return m.Size() +} +func (m *DeviceTaintRuleList) XXX_DiscardUnknown() { + xxx_messageInfo_DeviceTaintRuleList.DiscardUnknown(m) +} + +var xxx_messageInfo_DeviceTaintRuleList proto.InternalMessageInfo + +func (m *DeviceTaintRuleSpec) Reset() { *m = DeviceTaintRuleSpec{} } +func (*DeviceTaintRuleSpec) ProtoMessage() {} +func (*DeviceTaintRuleSpec) Descriptor() ([]byte, []int) { + return fileDescriptor_66649ee9bbcd89d2, []int{26} +} +func (m *DeviceTaintRuleSpec) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *DeviceTaintRuleSpec) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *DeviceTaintRuleSpec) XXX_Merge(src proto.Message) { + xxx_messageInfo_DeviceTaintRuleSpec.Merge(m, src) +} +func (m *DeviceTaintRuleSpec) XXX_Size() int { + return m.Size() +} +func (m *DeviceTaintRuleSpec) XXX_DiscardUnknown() { + xxx_messageInfo_DeviceTaintRuleSpec.DiscardUnknown(m) +} + +var xxx_messageInfo_DeviceTaintRuleSpec proto.InternalMessageInfo + +func (m *DeviceTaintSelector) Reset() { *m = DeviceTaintSelector{} } +func (*DeviceTaintSelector) ProtoMessage() {} +func (*DeviceTaintSelector) Descriptor() ([]byte, []int) { + return fileDescriptor_66649ee9bbcd89d2, []int{27} +} +func (m *DeviceTaintSelector) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *DeviceTaintSelector) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *DeviceTaintSelector) XXX_Merge(src proto.Message) { + xxx_messageInfo_DeviceTaintSelector.Merge(m, src) +} +func (m *DeviceTaintSelector) XXX_Size() int { + return m.Size() +} +func (m *DeviceTaintSelector) XXX_DiscardUnknown() { + xxx_messageInfo_DeviceTaintSelector.DiscardUnknown(m) +} + +var xxx_messageInfo_DeviceTaintSelector proto.InternalMessageInfo + +func (m *DeviceToleration) Reset() { *m = DeviceToleration{} } +func (*DeviceToleration) ProtoMessage() {} +func (*DeviceToleration) Descriptor() ([]byte, []int) { + return fileDescriptor_66649ee9bbcd89d2, []int{28} +} +func (m *DeviceToleration) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *DeviceToleration) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *DeviceToleration) XXX_Merge(src proto.Message) { + xxx_messageInfo_DeviceToleration.Merge(m, src) +} +func (m *DeviceToleration) XXX_Size() int { + return m.Size() +} +func (m *DeviceToleration) XXX_DiscardUnknown() { + xxx_messageInfo_DeviceToleration.DiscardUnknown(m) +} + +var xxx_messageInfo_DeviceToleration proto.InternalMessageInfo + func (m *NetworkDeviceData) Reset() { *m = NetworkDeviceData{} } func (*NetworkDeviceData) ProtoMessage() {} func (*NetworkDeviceData) Descriptor() ([]byte, []int) { - return fileDescriptor_66649ee9bbcd89d2, []int{19} + return fileDescriptor_66649ee9bbcd89d2, []int{29} } func (m *NetworkDeviceData) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -612,7 +893,7 @@ var xxx_messageInfo_NetworkDeviceData proto.InternalMessageInfo func (m *OpaqueDeviceConfiguration) Reset() { *m = OpaqueDeviceConfiguration{} } func (*OpaqueDeviceConfiguration) ProtoMessage() {} func (*OpaqueDeviceConfiguration) Descriptor() ([]byte, []int) { - return fileDescriptor_66649ee9bbcd89d2, []int{20} + return fileDescriptor_66649ee9bbcd89d2, []int{30} } func (m *OpaqueDeviceConfiguration) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -640,7 +921,7 @@ var xxx_messageInfo_OpaqueDeviceConfiguration proto.InternalMessageInfo func (m *ResourceClaim) Reset() { *m = ResourceClaim{} } func (*ResourceClaim) ProtoMessage() {} func (*ResourceClaim) Descriptor() ([]byte, []int) { - return fileDescriptor_66649ee9bbcd89d2, []int{21} + return fileDescriptor_66649ee9bbcd89d2, []int{31} } func (m *ResourceClaim) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -668,7 +949,7 @@ var xxx_messageInfo_ResourceClaim proto.InternalMessageInfo func (m *ResourceClaimConsumerReference) Reset() { *m = ResourceClaimConsumerReference{} } func (*ResourceClaimConsumerReference) ProtoMessage() {} func (*ResourceClaimConsumerReference) Descriptor() ([]byte, []int) { - return fileDescriptor_66649ee9bbcd89d2, []int{22} + return fileDescriptor_66649ee9bbcd89d2, []int{32} } func (m *ResourceClaimConsumerReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -696,7 +977,7 @@ var xxx_messageInfo_ResourceClaimConsumerReference proto.InternalMessageInfo func (m *ResourceClaimList) Reset() { *m = ResourceClaimList{} } func (*ResourceClaimList) ProtoMessage() {} func (*ResourceClaimList) Descriptor() ([]byte, []int) { - return fileDescriptor_66649ee9bbcd89d2, []int{23} + return fileDescriptor_66649ee9bbcd89d2, []int{33} } func (m *ResourceClaimList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -724,7 +1005,7 @@ var xxx_messageInfo_ResourceClaimList proto.InternalMessageInfo func (m *ResourceClaimSpec) Reset() { *m = ResourceClaimSpec{} } func (*ResourceClaimSpec) ProtoMessage() {} func (*ResourceClaimSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_66649ee9bbcd89d2, []int{24} + return fileDescriptor_66649ee9bbcd89d2, []int{34} } func (m *ResourceClaimSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -752,7 +1033,7 @@ var xxx_messageInfo_ResourceClaimSpec proto.InternalMessageInfo func (m *ResourceClaimStatus) Reset() { *m = ResourceClaimStatus{} } func (*ResourceClaimStatus) ProtoMessage() {} func (*ResourceClaimStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_66649ee9bbcd89d2, []int{25} + return fileDescriptor_66649ee9bbcd89d2, []int{35} } func (m *ResourceClaimStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -780,7 +1061,7 @@ var xxx_messageInfo_ResourceClaimStatus proto.InternalMessageInfo func (m *ResourceClaimTemplate) Reset() { *m = ResourceClaimTemplate{} } func (*ResourceClaimTemplate) ProtoMessage() {} func (*ResourceClaimTemplate) Descriptor() ([]byte, []int) { - return fileDescriptor_66649ee9bbcd89d2, []int{26} + return fileDescriptor_66649ee9bbcd89d2, []int{36} } func (m *ResourceClaimTemplate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -808,7 +1089,7 @@ var xxx_messageInfo_ResourceClaimTemplate proto.InternalMessageInfo func (m *ResourceClaimTemplateList) Reset() { *m = ResourceClaimTemplateList{} } func (*ResourceClaimTemplateList) ProtoMessage() {} func (*ResourceClaimTemplateList) Descriptor() ([]byte, []int) { - return fileDescriptor_66649ee9bbcd89d2, []int{27} + return fileDescriptor_66649ee9bbcd89d2, []int{37} } func (m *ResourceClaimTemplateList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -836,7 +1117,7 @@ var xxx_messageInfo_ResourceClaimTemplateList proto.InternalMessageInfo func (m *ResourceClaimTemplateSpec) Reset() { *m = ResourceClaimTemplateSpec{} } func (*ResourceClaimTemplateSpec) ProtoMessage() {} func (*ResourceClaimTemplateSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_66649ee9bbcd89d2, []int{28} + return fileDescriptor_66649ee9bbcd89d2, []int{38} } func (m *ResourceClaimTemplateSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -864,7 +1145,7 @@ var xxx_messageInfo_ResourceClaimTemplateSpec proto.InternalMessageInfo func (m *ResourcePool) Reset() { *m = ResourcePool{} } func (*ResourcePool) ProtoMessage() {} func (*ResourcePool) Descriptor() ([]byte, []int) { - return fileDescriptor_66649ee9bbcd89d2, []int{29} + return fileDescriptor_66649ee9bbcd89d2, []int{39} } func (m *ResourcePool) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -892,7 +1173,7 @@ var xxx_messageInfo_ResourcePool proto.InternalMessageInfo func (m *ResourceSlice) Reset() { *m = ResourceSlice{} } func (*ResourceSlice) ProtoMessage() {} func (*ResourceSlice) Descriptor() ([]byte, []int) { - return fileDescriptor_66649ee9bbcd89d2, []int{30} + return fileDescriptor_66649ee9bbcd89d2, []int{40} } func (m *ResourceSlice) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -920,7 +1201,7 @@ var xxx_messageInfo_ResourceSlice proto.InternalMessageInfo func (m *ResourceSliceList) Reset() { *m = ResourceSliceList{} } func (*ResourceSliceList) ProtoMessage() {} func (*ResourceSliceList) Descriptor() ([]byte, []int) { - return fileDescriptor_66649ee9bbcd89d2, []int{31} + return fileDescriptor_66649ee9bbcd89d2, []int{41} } func (m *ResourceSliceList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -948,7 +1229,7 @@ var xxx_messageInfo_ResourceSliceList proto.InternalMessageInfo func (m *ResourceSliceSpec) Reset() { *m = ResourceSliceSpec{} } func (*ResourceSliceSpec) ProtoMessage() {} func (*ResourceSliceSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_66649ee9bbcd89d2, []int{32} + return fileDescriptor_66649ee9bbcd89d2, []int{42} } func (m *ResourceSliceSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -980,6 +1261,9 @@ func init() { proto.RegisterMapType((map[QualifiedName]DeviceAttribute)(nil), "k8s.io.api.resource.v1alpha3.BasicDevice.AttributesEntry") proto.RegisterMapType((map[QualifiedName]resource.Quantity)(nil), "k8s.io.api.resource.v1alpha3.BasicDevice.CapacityEntry") proto.RegisterType((*CELDeviceSelector)(nil), "k8s.io.api.resource.v1alpha3.CELDeviceSelector") + proto.RegisterType((*Counter)(nil), "k8s.io.api.resource.v1alpha3.Counter") + proto.RegisterType((*CounterSet)(nil), "k8s.io.api.resource.v1alpha3.CounterSet") + proto.RegisterMapType((map[string]Counter)(nil), "k8s.io.api.resource.v1alpha3.CounterSet.CountersEntry") proto.RegisterType((*Device)(nil), "k8s.io.api.resource.v1alpha3.Device") proto.RegisterType((*DeviceAllocationConfiguration)(nil), "k8s.io.api.resource.v1alpha3.DeviceAllocationConfiguration") proto.RegisterType((*DeviceAllocationResult)(nil), "k8s.io.api.resource.v1alpha3.DeviceAllocationResult") @@ -992,9 +1276,18 @@ func init() { proto.RegisterType((*DeviceClassSpec)(nil), "k8s.io.api.resource.v1alpha3.DeviceClassSpec") proto.RegisterType((*DeviceConfiguration)(nil), "k8s.io.api.resource.v1alpha3.DeviceConfiguration") proto.RegisterType((*DeviceConstraint)(nil), "k8s.io.api.resource.v1alpha3.DeviceConstraint") + proto.RegisterType((*DeviceCounterConsumption)(nil), "k8s.io.api.resource.v1alpha3.DeviceCounterConsumption") + proto.RegisterMapType((map[string]Counter)(nil), "k8s.io.api.resource.v1alpha3.DeviceCounterConsumption.CountersEntry") proto.RegisterType((*DeviceRequest)(nil), "k8s.io.api.resource.v1alpha3.DeviceRequest") proto.RegisterType((*DeviceRequestAllocationResult)(nil), "k8s.io.api.resource.v1alpha3.DeviceRequestAllocationResult") proto.RegisterType((*DeviceSelector)(nil), "k8s.io.api.resource.v1alpha3.DeviceSelector") + proto.RegisterType((*DeviceSubRequest)(nil), "k8s.io.api.resource.v1alpha3.DeviceSubRequest") + proto.RegisterType((*DeviceTaint)(nil), "k8s.io.api.resource.v1alpha3.DeviceTaint") + proto.RegisterType((*DeviceTaintRule)(nil), "k8s.io.api.resource.v1alpha3.DeviceTaintRule") + proto.RegisterType((*DeviceTaintRuleList)(nil), "k8s.io.api.resource.v1alpha3.DeviceTaintRuleList") + proto.RegisterType((*DeviceTaintRuleSpec)(nil), "k8s.io.api.resource.v1alpha3.DeviceTaintRuleSpec") + proto.RegisterType((*DeviceTaintSelector)(nil), "k8s.io.api.resource.v1alpha3.DeviceTaintSelector") + proto.RegisterType((*DeviceToleration)(nil), "k8s.io.api.resource.v1alpha3.DeviceToleration") proto.RegisterType((*NetworkDeviceData)(nil), "k8s.io.api.resource.v1alpha3.NetworkDeviceData") proto.RegisterType((*OpaqueDeviceConfiguration)(nil), "k8s.io.api.resource.v1alpha3.OpaqueDeviceConfiguration") proto.RegisterType((*ResourceClaim)(nil), "k8s.io.api.resource.v1alpha3.ResourceClaim") @@ -1016,134 +1309,172 @@ func init() { } var fileDescriptor_66649ee9bbcd89d2 = []byte{ - // 2030 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x19, 0xcd, 0x6f, 0x1c, 0x57, - 0xdd, 0xb3, 0xe3, 0xcf, 0xdf, 0xfa, 0x2b, 0x2f, 0xa4, 0x38, 0xa6, 0xec, 0x3a, 0x53, 0x04, 0x4e, - 0x9b, 0xee, 0x36, 0x4e, 0xd5, 0x16, 0xc2, 0x01, 0x8f, 0xed, 0x06, 0x47, 0x89, 0xe3, 0x3c, 0xb7, - 0x11, 0x81, 0x12, 0x78, 0x9e, 0x7d, 0xb6, 0x07, 0xcf, 0xce, 0x4c, 0xe7, 0xbd, 0x71, 0xea, 0x0b, - 0xaa, 0xe0, 0x1e, 0xf1, 0x0f, 0x20, 0x0e, 0x48, 0x48, 0x5c, 0x80, 0xff, 0x00, 0x24, 0x90, 0x88, - 0xe0, 0x12, 0x09, 0x0e, 0x3d, 0x2d, 0xcd, 0x22, 0xce, 0xdc, 0x73, 0x42, 0xef, 0xcd, 0x9b, 0xcf, - 0xdd, 0x71, 0xc6, 0x55, 0xb1, 0xd2, 0xdb, 0xce, 0xef, 0xfb, 0xfd, 0xbe, 0xdf, 0x5b, 0xb8, 0x72, - 0xf8, 0x0e, 0x6b, 0xd9, 0x5e, 0x9b, 0xf8, 0x76, 0x3b, 0xa0, 0xcc, 0x0b, 0x03, 0x8b, 0xb6, 0x8f, - 0xae, 0x12, 0xc7, 0x3f, 0x20, 0xd7, 0xda, 0xfb, 0xd4, 0xa5, 0x01, 0xe1, 0xb4, 0xd3, 0xf2, 0x03, - 0x8f, 0x7b, 0xe8, 0xe5, 0x88, 0xba, 0x45, 0x7c, 0xbb, 0x15, 0x53, 0xb7, 0x62, 0xea, 0xc5, 0xd7, - 0xf7, 0x6d, 0x7e, 0x10, 0xee, 0xb6, 0x2c, 0xaf, 0xdb, 0xde, 0xf7, 0xf6, 0xbd, 0xb6, 0x64, 0xda, - 0x0d, 0xf7, 0xe4, 0x97, 0xfc, 0x90, 0xbf, 0x22, 0x61, 0x8b, 0x46, 0x46, 0xb5, 0xe5, 0x05, 0x42, - 0x6d, 0x51, 0xe1, 0xe2, 0x9b, 0x29, 0x4d, 0x97, 0x58, 0x07, 0xb6, 0x4b, 0x83, 0xe3, 0xb6, 0x7f, - 0xb8, 0x9f, 0xb7, 0xf7, 0x34, 0x5c, 0xac, 0xdd, 0xa5, 0x9c, 0x0c, 0xd3, 0xd5, 0x2e, 0xe3, 0x0a, - 0x42, 0x97, 0xdb, 0xdd, 0x41, 0x35, 0x6f, 0x3d, 0x8f, 0x81, 0x59, 0x07, 0xb4, 0x4b, 0x8a, 0x7c, - 0xc6, 0xaf, 0x75, 0xb8, 0xb0, 0xea, 0x38, 0x9e, 0x25, 0x60, 0xeb, 0xf4, 0xc8, 0xb6, 0xe8, 0x0e, - 0x27, 0x3c, 0x64, 0xe8, 0xeb, 0x30, 0xde, 0x09, 0xec, 0x23, 0x1a, 0x2c, 0x68, 0x4b, 0xda, 0xf2, - 0x94, 0x39, 0xfb, 0xb8, 0xd7, 0x1c, 0xe9, 0xf7, 0x9a, 0xe3, 0xeb, 0x12, 0x8a, 0x15, 0x16, 0x2d, - 0xc1, 0xa8, 0xef, 0x79, 0xce, 0x42, 0x4d, 0x52, 0x4d, 0x2b, 0xaa, 0xd1, 0x6d, 0xcf, 0x73, 0xb0, - 0xc4, 0x48, 0x49, 0x52, 0xf2, 0x82, 0x5e, 0x90, 0x24, 0xa1, 0x58, 0x61, 0x91, 0x05, 0x60, 0x79, - 0x6e, 0xc7, 0xe6, 0xb6, 0xe7, 0xb2, 0x85, 0xd1, 0x25, 0x7d, 0xb9, 0xbe, 0xd2, 0x6e, 0xa5, 0x61, - 0x4e, 0x0e, 0xd6, 0xf2, 0x0f, 0xf7, 0x05, 0x80, 0xb5, 0x84, 0xff, 0x5a, 0x47, 0x57, 0x5b, 0x6b, - 0x31, 0x9f, 0x89, 0x94, 0x70, 0x48, 0x40, 0x0c, 0x67, 0xc4, 0xa2, 0x3b, 0x30, 0xda, 0x21, 0x9c, - 0x2c, 0x8c, 0x2d, 0x69, 0xcb, 0xf5, 0x95, 0xd7, 0x4b, 0xc5, 0x2b, 0xbf, 0xb5, 0x30, 0x79, 0xb8, - 0xf1, 0x11, 0xa7, 0x2e, 0x13, 0xc2, 0x93, 0xd3, 0xad, 0x13, 0x4e, 0xb0, 0x14, 0x84, 0x76, 0xa1, - 0xee, 0x52, 0xfe, 0xd0, 0x0b, 0x0e, 0x05, 0x70, 0x61, 0x5c, 0xca, 0xcd, 0x9a, 0x3d, 0x98, 0x9d, - 0xad, 0x2d, 0xc5, 0x20, 0xcf, 0x2d, 0xd8, 0xcc, 0xb9, 0x7e, 0xaf, 0x59, 0xdf, 0x4a, 0xe5, 0xe0, - 0xac, 0x50, 0xe3, 0xef, 0x1a, 0xcc, 0xab, 0x28, 0xd9, 0x9e, 0x8b, 0x29, 0x0b, 0x1d, 0x8e, 0x7e, - 0x04, 0x13, 0x91, 0xe3, 0x98, 0x8c, 0x50, 0x7d, 0xe5, 0xcd, 0x93, 0x95, 0x46, 0xda, 0x8a, 0x62, - 0xcc, 0x39, 0x75, 0xa6, 0x89, 0x08, 0xcf, 0x70, 0x2c, 0x15, 0xdd, 0x83, 0x69, 0xd7, 0xeb, 0xd0, - 0x1d, 0xea, 0x50, 0x8b, 0x7b, 0x81, 0x8c, 0x5e, 0x7d, 0x65, 0x29, 0xab, 0x45, 0xd4, 0x8a, 0xf0, - 0xff, 0x56, 0x86, 0xce, 0x9c, 0xef, 0xf7, 0x9a, 0xd3, 0x59, 0x08, 0xce, 0xc9, 0x31, 0x3e, 0xd5, - 0xa1, 0x6e, 0x12, 0x66, 0x5b, 0x91, 0x46, 0xf4, 0x53, 0x00, 0xc2, 0x79, 0x60, 0xef, 0x86, 0x5c, - 0x9e, 0x45, 0xc4, 0xfd, 0x9b, 0x27, 0x9f, 0x25, 0xc3, 0xde, 0x5a, 0x4d, 0x78, 0x37, 0x5c, 0x1e, - 0x1c, 0x9b, 0xaf, 0xc4, 0x19, 0x90, 0x22, 0x7e, 0xf6, 0xaf, 0xe6, 0xcc, 0xdd, 0x90, 0x38, 0xf6, - 0x9e, 0x4d, 0x3b, 0x5b, 0xa4, 0x4b, 0x71, 0x46, 0x23, 0x3a, 0x82, 0x49, 0x8b, 0xf8, 0xc4, 0xb2, - 0xf9, 0xf1, 0x42, 0x4d, 0x6a, 0x7f, 0xbb, 0xba, 0xf6, 0x35, 0xc5, 0x19, 0xe9, 0xbe, 0xa4, 0x74, - 0x4f, 0xc6, 0xe0, 0x41, 0xcd, 0x89, 0xae, 0x45, 0x07, 0xe6, 0x0a, 0xb6, 0xa3, 0x79, 0xd0, 0x0f, - 0xe9, 0x71, 0x54, 0x71, 0x58, 0xfc, 0x44, 0x6b, 0x30, 0x76, 0x44, 0x9c, 0x90, 0xca, 0xfa, 0xca, - 0x27, 0x6c, 0x79, 0x8c, 0x63, 0xa9, 0x38, 0xe2, 0xfd, 0x56, 0xed, 0x1d, 0x6d, 0xf1, 0x10, 0x66, - 0x72, 0xb6, 0x0e, 0xd1, 0xb5, 0x9e, 0xd7, 0xd5, 0x3a, 0xa9, 0xf6, 0x52, 0xe5, 0x77, 0x43, 0xe2, - 0x72, 0x9b, 0x1f, 0x67, 0x94, 0x19, 0x37, 0xe0, 0xdc, 0xda, 0xc6, 0x2d, 0xd5, 0x4f, 0x54, 0xdc, - 0xd1, 0x0a, 0x00, 0xfd, 0xc8, 0x0f, 0x28, 0x13, 0xb5, 0xa4, 0xba, 0x4a, 0x52, 0xae, 0x1b, 0x09, - 0x06, 0x67, 0xa8, 0x8c, 0x23, 0x50, 0x5d, 0x42, 0xf4, 0x19, 0x97, 0x74, 0xa9, 0xe2, 0x4b, 0x2a, - 0x51, 0xfa, 0x54, 0x62, 0xd0, 0x4d, 0x18, 0xdb, 0x15, 0x91, 0x51, 0xe6, 0x5f, 0xae, 0x1c, 0x44, - 0x73, 0xaa, 0xdf, 0x6b, 0x8e, 0x49, 0x00, 0x8e, 0x44, 0x18, 0x8f, 0x6a, 0xf0, 0xd5, 0x62, 0xc1, - 0xac, 0x79, 0xee, 0x9e, 0xbd, 0x1f, 0x06, 0xf2, 0x03, 0x7d, 0x07, 0xc6, 0x23, 0x91, 0xca, 0xa2, - 0xe5, 0xb8, 0xab, 0xed, 0x48, 0xe8, 0xb3, 0x5e, 0xf3, 0xa5, 0x22, 0x6b, 0x84, 0xc1, 0x8a, 0x0f, - 0x2d, 0xc3, 0x64, 0x40, 0x3f, 0x0c, 0x29, 0xe3, 0x4c, 0xe6, 0xdd, 0x94, 0x39, 0x2d, 0x52, 0x07, - 0x2b, 0x18, 0x4e, 0xb0, 0xe8, 0x63, 0x0d, 0xce, 0x47, 0x55, 0x99, 0xb3, 0x41, 0x55, 0xe4, 0xd5, - 0x2a, 0x39, 0x91, 0x63, 0x34, 0xbf, 0xa2, 0x8c, 0x3d, 0x3f, 0x04, 0x89, 0x87, 0xa9, 0x32, 0xfe, - 0xa3, 0xc1, 0x4b, 0xc3, 0x3b, 0x08, 0xda, 0x83, 0x89, 0x40, 0xfe, 0x8a, 0x8b, 0xf7, 0x7a, 0x15, - 0x83, 0xd4, 0x31, 0xcb, 0xfb, 0x51, 0xf4, 0xcd, 0x70, 0x2c, 0x1c, 0x59, 0x30, 0x6e, 0x49, 0x9b, - 0x54, 0x95, 0x5e, 0x3f, 0x5d, 0xbf, 0xcb, 0x7b, 0x20, 0x19, 0x42, 0x11, 0x18, 0x2b, 0xd1, 0xc6, - 0x6f, 0x35, 0x98, 0x2b, 0x54, 0x11, 0x6a, 0x80, 0x6e, 0xbb, 0x5c, 0xa6, 0x95, 0x1e, 0xc5, 0x68, - 0xd3, 0xe5, 0xf7, 0x44, 0xb2, 0x63, 0x81, 0x40, 0x97, 0x60, 0x74, 0x57, 0x8c, 0x40, 0x11, 0x8e, - 0x49, 0x73, 0xa6, 0xdf, 0x6b, 0x4e, 0x99, 0x9e, 0xe7, 0x44, 0x14, 0x12, 0x85, 0xbe, 0x01, 0xe3, - 0x8c, 0x07, 0xb6, 0xbb, 0xbf, 0x30, 0x2a, 0xb3, 0x45, 0xf6, 0xfb, 0x1d, 0x09, 0x89, 0xc8, 0x14, - 0x1a, 0xbd, 0x0a, 0x13, 0x47, 0x34, 0x90, 0x15, 0x32, 0x26, 0x29, 0x65, 0x37, 0xbd, 0x17, 0x81, - 0x22, 0xd2, 0x98, 0xc0, 0xf8, 0x7d, 0x0d, 0xea, 0x2a, 0x80, 0x0e, 0xb1, 0xbb, 0xe8, 0x7e, 0x26, - 0xa1, 0xa2, 0x48, 0xbc, 0x76, 0x8a, 0x48, 0x98, 0xf3, 0x71, 0xf3, 0x1a, 0x92, 0x81, 0x14, 0xea, - 0x96, 0xe7, 0x32, 0x1e, 0x10, 0xdb, 0x55, 0xe9, 0x9a, 0x6f, 0x10, 0x27, 0x25, 0x9e, 0x62, 0x33, - 0xcf, 0x2b, 0x05, 0xf5, 0x14, 0xc6, 0x70, 0x56, 0x2e, 0x7a, 0x90, 0x84, 0x58, 0x97, 0x1a, 0xde, - 0xaa, 0xa4, 0x41, 0x1c, 0xbe, 0x5a, 0x74, 0xff, 0xaa, 0xc1, 0x42, 0x19, 0x53, 0xae, 0x1e, 0xb5, - 0xcf, 0x54, 0x8f, 0xb5, 0xb3, 0xab, 0xc7, 0x3f, 0x69, 0x99, 0xd8, 0x33, 0x86, 0x7e, 0x0c, 0x93, - 0x62, 0x19, 0x92, 0xbb, 0x4d, 0xb4, 0x0e, 0xbc, 0x51, 0x6d, 0x75, 0xba, 0xb3, 0xfb, 0x13, 0x6a, - 0xf1, 0xdb, 0x94, 0x93, 0xb4, 0x19, 0xa7, 0x30, 0x9c, 0x48, 0x15, 0x9b, 0x13, 0xf3, 0xa9, 0x75, - 0x9a, 0x41, 0x24, 0x4d, 0xdb, 0xf1, 0xa9, 0x95, 0xf6, 0x6b, 0xf1, 0x85, 0xa5, 0x20, 0xe3, 0x97, - 0xd9, 0x60, 0x30, 0x96, 0x0f, 0x46, 0x99, 0x8b, 0xb5, 0xb3, 0x73, 0xf1, 0x1f, 0x93, 0x56, 0x20, - 0xed, 0xbb, 0x65, 0x33, 0x8e, 0x3e, 0x18, 0x70, 0x73, 0xab, 0x9a, 0x9b, 0x05, 0xb7, 0x74, 0x72, - 0x52, 0x65, 0x31, 0x24, 0xe3, 0xe2, 0x2d, 0x18, 0xb3, 0x39, 0xed, 0xc6, 0xf5, 0x75, 0xb9, 0xb2, - 0x8f, 0xcd, 0x19, 0x25, 0x75, 0x6c, 0x53, 0xf0, 0xe3, 0x48, 0x8c, 0xf1, 0x24, 0x7f, 0x02, 0xe1, - 0x7b, 0xf4, 0x43, 0x98, 0x62, 0x6a, 0x22, 0xc7, 0x5d, 0xe2, 0x4a, 0x15, 0x3d, 0xc9, 0x7a, 0x77, - 0x4e, 0xa9, 0x9a, 0x8a, 0x21, 0x0c, 0xa7, 0x12, 0x33, 0x15, 0x5c, 0x3b, 0x55, 0x05, 0x17, 0xe2, - 0x5f, 0x5a, 0xc1, 0x01, 0x0c, 0x0b, 0x20, 0xfa, 0x01, 0x8c, 0x7b, 0x3e, 0xf9, 0x30, 0xa4, 0x2a, - 0x2a, 0xcf, 0xd9, 0xe0, 0xee, 0x48, 0xda, 0x61, 0x69, 0x02, 0x42, 0x67, 0x84, 0xc6, 0x4a, 0xa4, - 0xf1, 0x48, 0x83, 0xf9, 0x62, 0x33, 0x3b, 0x45, 0xb7, 0xd8, 0x86, 0xd9, 0x2e, 0xe1, 0xd6, 0x41, - 0x32, 0x50, 0xd4, 0x5d, 0x69, 0xb9, 0xdf, 0x6b, 0xce, 0xde, 0xce, 0x61, 0x9e, 0xf5, 0x9a, 0xe8, - 0xdd, 0xd0, 0x71, 0x8e, 0xf3, 0x3b, 0x63, 0x81, 0xdf, 0xf8, 0xb9, 0x0e, 0x33, 0xb9, 0xde, 0x5d, - 0x61, 0x3b, 0x5a, 0x85, 0xb9, 0x4e, 0xea, 0x6c, 0x81, 0x50, 0x66, 0x7c, 0x59, 0x11, 0x67, 0x33, - 0x45, 0xf2, 0x15, 0xe9, 0xf3, 0xa9, 0xa3, 0x7f, 0xee, 0xa9, 0x73, 0x0f, 0x66, 0x49, 0x32, 0xad, - 0x6f, 0x7b, 0x1d, 0xaa, 0x66, 0x65, 0x4b, 0x71, 0xcd, 0xae, 0xe6, 0xb0, 0xcf, 0x7a, 0xcd, 0x2f, - 0x15, 0x67, 0xbc, 0x80, 0xe3, 0x82, 0x14, 0xf4, 0x0a, 0x8c, 0x59, 0x5e, 0xe8, 0x72, 0x39, 0x50, - 0xf5, 0xb4, 0x54, 0xd6, 0x04, 0x10, 0x47, 0x38, 0x74, 0x15, 0xea, 0xa4, 0xd3, 0xb5, 0xdd, 0x55, - 0xcb, 0xa2, 0x8c, 0xc9, 0x6b, 0xdc, 0x64, 0x34, 0xa5, 0x57, 0x53, 0x30, 0xce, 0xd2, 0x18, 0xff, - 0xd5, 0xe2, 0x1d, 0xb1, 0x64, 0x97, 0x41, 0x97, 0xc5, 0x66, 0x24, 0x51, 0x2a, 0x30, 0x99, 0xe5, - 0x46, 0x82, 0x71, 0x8c, 0xcf, 0x5c, 0xb7, 0x6b, 0x95, 0xae, 0xdb, 0x7a, 0x85, 0xeb, 0xf6, 0xe8, - 0x89, 0xd7, 0xed, 0xc2, 0x89, 0xc7, 0x2a, 0x9c, 0xf8, 0x03, 0x98, 0x2d, 0xec, 0xf4, 0x37, 0x41, - 0xb7, 0xa8, 0xa3, 0x8a, 0xee, 0x39, 0xb7, 0xde, 0x81, 0x1b, 0x81, 0x39, 0xd1, 0xef, 0x35, 0xf5, - 0xb5, 0x8d, 0x5b, 0x58, 0x08, 0x31, 0x7e, 0xa7, 0xc1, 0xb9, 0x81, 0x9b, 0x31, 0xba, 0x0e, 0x33, - 0xb6, 0xcb, 0x69, 0xb0, 0x47, 0x2c, 0xba, 0x95, 0xa6, 0xf8, 0x05, 0x75, 0xaa, 0x99, 0xcd, 0x2c, - 0x12, 0xe7, 0x69, 0xd1, 0x45, 0xd0, 0x6d, 0x3f, 0xde, 0xae, 0xa5, 0xb6, 0xcd, 0x6d, 0x86, 0x05, - 0x4c, 0xd4, 0xc3, 0x01, 0x09, 0x3a, 0x0f, 0x49, 0x40, 0x57, 0x3b, 0x1d, 0x71, 0xdf, 0x50, 0x3e, - 0x4d, 0xea, 0xe1, 0xbb, 0x79, 0x34, 0x2e, 0xd2, 0x1b, 0xbf, 0xd1, 0xe0, 0x62, 0x69, 0x27, 0xa9, - 0xfc, 0x80, 0x42, 0x00, 0x7c, 0x12, 0x90, 0x2e, 0xe5, 0x34, 0x60, 0x43, 0xa6, 0x6b, 0x85, 0x77, - 0x89, 0x64, 0x70, 0x6f, 0x27, 0x82, 0x70, 0x46, 0xa8, 0xf1, 0xab, 0x1a, 0xcc, 0x60, 0x15, 0x8f, - 0x68, 0x55, 0xfc, 0xff, 0xaf, 0x0b, 0x77, 0x73, 0xeb, 0xc2, 0x73, 0x52, 0x23, 0x67, 0x5c, 0xd9, - 0xc2, 0x80, 0xee, 0x8b, 0x25, 0x9a, 0xf0, 0x90, 0x55, 0xbb, 0xf8, 0xe4, 0x85, 0x4a, 0xc6, 0x34, - 0x08, 0xd1, 0x37, 0x56, 0x02, 0x8d, 0xbe, 0x06, 0x8d, 0x1c, 0xbd, 0xe8, 0xf4, 0x61, 0x97, 0x06, - 0x98, 0xee, 0xd1, 0x80, 0xba, 0x16, 0x45, 0x57, 0x60, 0x92, 0xf8, 0xf6, 0x8d, 0xc0, 0x0b, 0x7d, - 0x15, 0xd1, 0x64, 0x94, 0xaf, 0x6e, 0x6f, 0x4a, 0x38, 0x4e, 0x28, 0x04, 0x75, 0x6c, 0x91, 0xca, - 0xab, 0xcc, 0x7a, 0x1d, 0xc1, 0x71, 0x42, 0x91, 0xb4, 0xef, 0xd1, 0xd2, 0xf6, 0x6d, 0x82, 0x1e, - 0xda, 0x1d, 0x75, 0x27, 0x78, 0x43, 0x11, 0xe8, 0xef, 0x6f, 0xae, 0x3f, 0xeb, 0x35, 0x2f, 0x95, - 0x3d, 0xfe, 0xf1, 0x63, 0x9f, 0xb2, 0xd6, 0xfb, 0x9b, 0xeb, 0x58, 0x30, 0x1b, 0x7f, 0xd6, 0xe0, - 0x5c, 0xee, 0x90, 0x67, 0xb0, 0xd2, 0x6c, 0xe7, 0x57, 0x9a, 0xd7, 0x4e, 0x11, 0xb2, 0x92, 0xa5, - 0xc6, 0x2e, 0x1c, 0x42, 0x6e, 0x35, 0xef, 0x15, 0x1f, 0xc3, 0x2e, 0x57, 0xbe, 0x39, 0x94, 0xbf, - 0x80, 0x19, 0x7f, 0xab, 0xc1, 0xf9, 0x21, 0x59, 0x84, 0x1e, 0x00, 0xa4, 0x33, 0x66, 0x88, 0xd3, - 0x86, 0x28, 0x1c, 0xb8, 0xe7, 0xce, 0xca, 0x27, 0xaa, 0x14, 0x9a, 0x91, 0x88, 0x18, 0xd4, 0x03, - 0xca, 0x68, 0x70, 0x44, 0x3b, 0xef, 0x7a, 0x81, 0x72, 0xdd, 0xb7, 0x4f, 0xe1, 0xba, 0x81, 0xec, - 0x4d, 0xef, 0x5e, 0x38, 0x15, 0x8c, 0xb3, 0x5a, 0xd0, 0x83, 0xd4, 0x85, 0xd1, 0xdb, 0xeb, 0xb5, - 0x4a, 0x27, 0xca, 0x3f, 0x1b, 0x9f, 0xe0, 0xcc, 0x7f, 0x6a, 0x70, 0x21, 0x67, 0xe4, 0x7b, 0xb4, - 0xeb, 0x3b, 0x84, 0xd3, 0x33, 0x68, 0x46, 0xf7, 0x73, 0xcd, 0xe8, 0xed, 0x53, 0x78, 0x32, 0x36, - 0xb2, 0xf4, 0x16, 0xf3, 0x0f, 0x0d, 0x2e, 0x0e, 0xe5, 0x38, 0x83, 0xe2, 0xfa, 0x5e, 0xbe, 0xb8, - 0xae, 0x7d, 0x86, 0x73, 0x95, 0xdf, 0x1c, 0x2e, 0x96, 0xfa, 0xe1, 0x0b, 0x39, 0x3d, 0x8c, 0x3f, - 0x68, 0x30, 0x1d, 0x53, 0x8a, 0x75, 0xa9, 0xc2, 0xce, 0xbc, 0x02, 0xa0, 0xfe, 0x30, 0x89, 0x6f, - 0xf7, 0x7a, 0x6a, 0xf7, 0x8d, 0x04, 0x83, 0x33, 0x54, 0xe8, 0x26, 0xa0, 0xd8, 0xc2, 0x1d, 0x47, - 0x2e, 0x05, 0x62, 0xf5, 0xd4, 0x25, 0xef, 0xa2, 0xe2, 0x45, 0x78, 0x80, 0x02, 0x0f, 0xe1, 0x32, - 0xfe, 0xa2, 0xa5, 0x73, 0x5b, 0x82, 0x5f, 0x54, 0xcf, 0x4b, 0xe3, 0x4a, 0x3d, 0x9f, 0x9d, 0x3b, - 0x92, 0xf2, 0x85, 0x9d, 0x3b, 0xd2, 0xba, 0x92, 0x92, 0x78, 0xa4, 0x17, 0x4e, 0x21, 0x4b, 0xa1, - 0xea, 0x96, 0x77, 0x2b, 0xf3, 0x37, 0x59, 0x7d, 0xe5, 0xd5, 0x6a, 0xe6, 0x88, 0x34, 0x1d, 0xba, - 0xe3, 0x5f, 0x81, 0x49, 0xd7, 0xeb, 0x44, 0xfb, 0x70, 0x61, 0xbb, 0xd8, 0x52, 0x70, 0x9c, 0x50, - 0x0c, 0xfc, 0x91, 0x33, 0xfa, 0xf9, 0xfc, 0x91, 0x23, 0x37, 0x22, 0xc7, 0x11, 0x04, 0xf1, 0xf5, - 0x21, 0xdd, 0x88, 0x14, 0x1c, 0x27, 0x14, 0xe8, 0x4e, 0x3a, 0x5f, 0xc6, 0x65, 0x4c, 0xbe, 0x56, - 0x65, 0x44, 0x97, 0x0f, 0x14, 0xd3, 0x7c, 0xfc, 0xb4, 0x31, 0xf2, 0xe4, 0x69, 0x63, 0xe4, 0x93, - 0xa7, 0x8d, 0x91, 0x8f, 0xfb, 0x0d, 0xed, 0x71, 0xbf, 0xa1, 0x3d, 0xe9, 0x37, 0xb4, 0x4f, 0xfa, - 0x0d, 0xed, 0xd3, 0x7e, 0x43, 0xfb, 0xc5, 0xbf, 0x1b, 0x23, 0xdf, 0x7f, 0xf9, 0xa4, 0x7f, 0x95, - 0xff, 0x17, 0x00, 0x00, 0xff, 0xff, 0xbd, 0x60, 0x85, 0x64, 0x74, 0x1e, 0x00, 0x00, + // 2635 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x1a, 0x5b, 0x6f, 0x1c, 0x57, + 0x39, 0xb3, 0xbb, 0x5e, 0xaf, 0xbf, 0x8d, 0x1d, 0xfb, 0x84, 0x84, 0x8d, 0x49, 0x77, 0x93, 0x09, + 0x17, 0xa7, 0x75, 0xd6, 0x8d, 0x53, 0xb5, 0x85, 0x80, 0x84, 0xd7, 0x76, 0x52, 0xa7, 0x89, 0xe3, + 0x9c, 0x75, 0x03, 0x81, 0x12, 0x18, 0xcf, 0x1e, 0xdb, 0x83, 0x67, 0x67, 0xa6, 0x73, 0x66, 0x9d, + 0x5a, 0x42, 0xa8, 0xe2, 0x07, 0x54, 0xbc, 0xf2, 0x80, 0x2a, 0xf1, 0x50, 0x89, 0x17, 0xe0, 0x99, + 0x17, 0x90, 0x40, 0x6a, 0x04, 0x3c, 0x44, 0xa2, 0x42, 0x15, 0x12, 0x0b, 0x59, 0x84, 0xf8, 0x0b, + 0xc8, 0x4f, 0xe8, 0x5c, 0xe6, 0xba, 0x3b, 0xce, 0xac, 0x49, 0xac, 0x20, 0xf5, 0x6d, 0xf7, 0x3b, + 0xdf, 0xed, 0x7c, 0xf7, 0x73, 0xe6, 0xc0, 0xec, 0xce, 0xeb, 0xb4, 0x6e, 0xd8, 0x73, 0x9a, 0x63, + 0xcc, 0xb9, 0x84, 0xda, 0x1d, 0x57, 0x27, 0x73, 0xbb, 0x97, 0x35, 0xd3, 0xd9, 0xd6, 0xae, 0xcc, + 0x6d, 0x11, 0x8b, 0xb8, 0x9a, 0x47, 0x5a, 0x75, 0xc7, 0xb5, 0x3d, 0x1b, 0x9d, 0x15, 0xd8, 0x75, + 0xcd, 0x31, 0xea, 0x3e, 0x76, 0xdd, 0xc7, 0x9e, 0xbe, 0xb4, 0x65, 0x78, 0xdb, 0x9d, 0x8d, 0xba, + 0x6e, 0xb7, 0xe7, 0xb6, 0xec, 0x2d, 0x7b, 0x8e, 0x13, 0x6d, 0x74, 0x36, 0xf9, 0x3f, 0xfe, 0x87, + 0xff, 0x12, 0xcc, 0xa6, 0xd5, 0x88, 0x68, 0xdd, 0x76, 0x99, 0xd8, 0xa4, 0xc0, 0xe9, 0x57, 0x42, + 0x9c, 0xb6, 0xa6, 0x6f, 0x1b, 0x16, 0x71, 0xf7, 0xe6, 0x9c, 0x9d, 0xad, 0xb8, 0xbe, 0xc3, 0x50, + 0xd1, 0xb9, 0x36, 0xf1, 0xb4, 0x41, 0xb2, 0xe6, 0xd2, 0xa8, 0xdc, 0x8e, 0xe5, 0x19, 0xed, 0x7e, + 0x31, 0xaf, 0x3e, 0x89, 0x80, 0xea, 0xdb, 0xa4, 0xad, 0x25, 0xe9, 0xd4, 0x0f, 0xf2, 0x70, 0x6a, + 0xc1, 0x34, 0x6d, 0x9d, 0xc1, 0x96, 0xc8, 0xae, 0xa1, 0x93, 0xa6, 0xa7, 0x79, 0x1d, 0x8a, 0xbe, + 0x08, 0xc5, 0x96, 0x6b, 0xec, 0x12, 0xb7, 0xa2, 0x9c, 0x53, 0x66, 0xc6, 0x1a, 0x13, 0x0f, 0xbb, + 0xb5, 0x63, 0xbd, 0x6e, 0xad, 0xb8, 0xc4, 0xa1, 0x58, 0xae, 0xa2, 0x73, 0x50, 0x70, 0x6c, 0xdb, + 0xac, 0xe4, 0x38, 0xd6, 0x71, 0x89, 0x55, 0x58, 0xb3, 0x6d, 0x13, 0xf3, 0x15, 0xce, 0x89, 0x73, + 0xae, 0xe4, 0x13, 0x9c, 0x38, 0x14, 0xcb, 0x55, 0xa4, 0x03, 0xe8, 0xb6, 0xd5, 0x32, 0x3c, 0xc3, + 0xb6, 0x68, 0xa5, 0x70, 0x2e, 0x3f, 0x53, 0x9e, 0x9f, 0xab, 0x87, 0x6e, 0x0e, 0x36, 0x56, 0x77, + 0x76, 0xb6, 0x18, 0x80, 0xd6, 0x99, 0xfd, 0xea, 0xbb, 0x97, 0xeb, 0x8b, 0x3e, 0x5d, 0x03, 0x49, + 0xe6, 0x10, 0x80, 0x28, 0x8e, 0xb0, 0x45, 0x6f, 0x42, 0xa1, 0xa5, 0x79, 0x5a, 0x65, 0xe4, 0x9c, + 0x32, 0x53, 0x9e, 0xbf, 0x94, 0xca, 0x5e, 0xda, 0xad, 0x8e, 0xb5, 0x07, 0xcb, 0xef, 0x7a, 0xc4, + 0xa2, 0x8c, 0x79, 0x89, 0xed, 0x6c, 0x49, 0xf3, 0x34, 0xcc, 0x99, 0xa0, 0x0d, 0x28, 0x5b, 0xc4, + 0x7b, 0x60, 0xbb, 0x3b, 0x0c, 0x58, 0x29, 0x72, 0x9e, 0x51, 0x95, 0xfb, 0x23, 0xb3, 0xbe, 0x2a, + 0x09, 0xf8, 0x9e, 0x19, 0x59, 0xe3, 0x44, 0xaf, 0x5b, 0x2b, 0xaf, 0x86, 0x7c, 0x70, 0x94, 0xa9, + 0xfa, 0x47, 0x05, 0x26, 0xa5, 0x87, 0x0c, 0xdb, 0xc2, 0x84, 0x76, 0x4c, 0x0f, 0x7d, 0x17, 0x46, + 0x85, 0xd1, 0x28, 0xf7, 0x4e, 0x79, 0xfe, 0x95, 0x83, 0x85, 0x0a, 0x69, 0x49, 0x36, 0x8d, 0x13, + 0xd2, 0x58, 0xa3, 0x62, 0x9d, 0x62, 0x9f, 0x2b, 0xba, 0x0b, 0xc7, 0x2d, 0xbb, 0x45, 0x9a, 0xc4, + 0x24, 0xba, 0x67, 0xbb, 0xdc, 0x73, 0xe5, 0xf9, 0x73, 0x51, 0x29, 0x2c, 0x4f, 0x98, 0xed, 0x57, + 0x23, 0x78, 0x8d, 0xc9, 0x5e, 0xb7, 0x76, 0x3c, 0x0a, 0xc1, 0x31, 0x3e, 0xea, 0xdf, 0x8a, 0x50, + 0x6e, 0x68, 0xd4, 0xd0, 0x85, 0x44, 0xf4, 0x43, 0x00, 0xcd, 0xf3, 0x5c, 0x63, 0xa3, 0xe3, 0xf1, + 0xbd, 0x30, 0x9f, 0x7f, 0xf9, 0xe0, 0xbd, 0x44, 0xc8, 0xeb, 0x0b, 0x01, 0xed, 0xb2, 0xe5, 0xb9, + 0x7b, 0x8d, 0x0b, 0xbe, 0xf7, 0xc3, 0x85, 0x1f, 0xfd, 0xbd, 0x36, 0x7e, 0xa7, 0xa3, 0x99, 0xc6, + 0xa6, 0x41, 0x5a, 0xab, 0x5a, 0x9b, 0xe0, 0x88, 0x44, 0xb4, 0x0b, 0x25, 0x5d, 0x73, 0x34, 0xdd, + 0xf0, 0xf6, 0x2a, 0x39, 0x2e, 0xfd, 0xb5, 0xec, 0xd2, 0x17, 0x25, 0xa5, 0x90, 0x7d, 0x5e, 0xca, + 0x2e, 0xf9, 0xe0, 0x7e, 0xc9, 0x81, 0x2c, 0xf4, 0x03, 0x98, 0xd4, 0x6d, 0x8b, 0x76, 0xda, 0x84, + 0x2e, 0xda, 0x1d, 0xcb, 0x23, 0x2e, 0xad, 0xe4, 0xb9, 0xfc, 0x57, 0xb3, 0x78, 0x52, 0xd2, 0x2c, + 0x72, 0x16, 0x0e, 0x0f, 0xfc, 0x8a, 0x14, 0x3f, 0xb9, 0x98, 0xe0, 0x8b, 0xfb, 0x24, 0xa1, 0x19, + 0x28, 0x31, 0xaf, 0x30, 0x9d, 0x2a, 0x05, 0x91, 0xb7, 0x4c, 0xf1, 0x55, 0x09, 0xc3, 0xc1, 0x6a, + 0x5f, 0x1c, 0x8c, 0x3c, 0x9d, 0x38, 0x60, 0x1a, 0x68, 0xa6, 0xc9, 0x10, 0x28, 0x4f, 0x9b, 0x92, + 0xd0, 0x60, 0x41, 0xc2, 0x70, 0xb0, 0x8a, 0xee, 0x40, 0xd1, 0xd3, 0x0c, 0xcb, 0xa3, 0x95, 0x51, + 0x6e, 0x9f, 0x8b, 0x59, 0xec, 0xb3, 0xce, 0x28, 0xc2, 0x42, 0xc3, 0xff, 0x52, 0x2c, 0x19, 0x4d, + 0x9b, 0x70, 0x22, 0x11, 0x38, 0x68, 0x12, 0xf2, 0x3b, 0x64, 0x4f, 0x94, 0x3a, 0xcc, 0x7e, 0xa2, + 0x45, 0x18, 0xd9, 0xd5, 0xcc, 0x0e, 0xe1, 0x85, 0x2d, 0x5e, 0x29, 0xd2, 0x13, 0xcc, 0xe7, 0x8a, + 0x05, 0xed, 0x57, 0x72, 0xaf, 0x2b, 0xd3, 0x3b, 0x30, 0x1e, 0x0b, 0x94, 0x01, 0xb2, 0x96, 0xe2, + 0xb2, 0xea, 0x07, 0x15, 0xbd, 0x50, 0xf8, 0x9d, 0x8e, 0x66, 0x79, 0x86, 0xb7, 0x17, 0x11, 0xa6, + 0x5e, 0x87, 0xa9, 0xc5, 0xe5, 0x9b, 0xb2, 0x90, 0xfb, 0xc6, 0x9e, 0x07, 0x20, 0xef, 0x3a, 0x2e, + 0xa1, 0xac, 0x88, 0xc9, 0x72, 0x1e, 0xd4, 0xc9, 0xe5, 0x60, 0x05, 0x47, 0xb0, 0xd4, 0xfb, 0x30, + 0x2a, 0xc3, 0x05, 0x35, 0x7d, 0xed, 0x94, 0xc3, 0x68, 0xd7, 0x18, 0x97, 0x92, 0x46, 0xee, 0x32, + 0x26, 0x52, 0x59, 0xf5, 0x3f, 0x0a, 0x80, 0x14, 0xd0, 0x24, 0x1e, 0xeb, 0x22, 0x16, 0x8b, 0x46, + 0x25, 0xde, 0x45, 0x78, 0x34, 0xf2, 0x15, 0xd4, 0x82, 0x92, 0xee, 0x67, 0x4a, 0x2e, 0x4b, 0xa6, + 0x84, 0xdc, 0xfd, 0x9f, 0xb2, 0x48, 0x4c, 0x06, 0x89, 0xea, 0x67, 0x48, 0xc0, 0x79, 0x7a, 0x03, + 0xc6, 0x63, 0xc8, 0x03, 0x9c, 0x75, 0x35, 0xee, 0xac, 0x2f, 0x64, 0xd2, 0x22, 0xea, 0xa3, 0x5d, + 0x90, 0x9d, 0x2f, 0xc3, 0xae, 0x6f, 0xc0, 0xc8, 0x06, 0xab, 0x38, 0x52, 0xd8, 0xc5, 0xcc, 0xc5, + 0xa9, 0x31, 0xc6, 0x4c, 0xce, 0x01, 0x58, 0xb0, 0x50, 0xdf, 0xcf, 0xc1, 0x0b, 0xc9, 0x46, 0xb0, + 0x68, 0x5b, 0x9b, 0xc6, 0x56, 0xc7, 0xe5, 0x7f, 0xd0, 0xd7, 0xa1, 0x28, 0x58, 0x4a, 0x8d, 0x66, + 0xfc, 0x04, 0x6a, 0x72, 0xe8, 0x7e, 0xb7, 0x76, 0x3a, 0x49, 0x2a, 0x56, 0xb0, 0xa4, 0x63, 0x79, + 0xed, 0x92, 0x77, 0x3a, 0x84, 0x7a, 0xc2, 0x4b, 0xb2, 0xb2, 0x60, 0x09, 0xc3, 0xc1, 0x2a, 0x7a, + 0x4f, 0x81, 0x93, 0x2d, 0x59, 0xcc, 0x22, 0x3a, 0xc8, 0x4e, 0x73, 0x39, 0x5b, 0x15, 0x8c, 0x10, + 0x36, 0x3e, 0x27, 0x95, 0x3d, 0x39, 0x60, 0x11, 0x0f, 0x12, 0xa5, 0xfe, 0x4b, 0x81, 0xd3, 0x83, + 0x3b, 0x23, 0xda, 0x84, 0x51, 0x97, 0xff, 0xf2, 0x9b, 0xd2, 0xd5, 0x2c, 0x0a, 0xc9, 0x6d, 0xa6, + 0xf7, 0x59, 0xf1, 0x9f, 0x62, 0x9f, 0x39, 0xd2, 0xa1, 0xa8, 0x73, 0x9d, 0x64, 0x4c, 0x5f, 0x1d, + 0xae, 0x8f, 0xc7, 0x2d, 0x10, 0xd4, 0x3b, 0x01, 0xc6, 0x92, 0xb5, 0xfa, 0x73, 0x05, 0x4e, 0x24, + 0x0a, 0x14, 0xaa, 0x42, 0xde, 0xb0, 0x3c, 0x1e, 0x56, 0x79, 0xe1, 0xa3, 0x15, 0xcb, 0x13, 0x19, + 0xca, 0x16, 0xd0, 0x79, 0x28, 0x6c, 0xb0, 0xb1, 0x2e, 0xcf, 0x8b, 0xf3, 0x78, 0xaf, 0x5b, 0x1b, + 0x6b, 0xd8, 0xb6, 0x29, 0x30, 0xf8, 0x12, 0xfa, 0x12, 0x14, 0xa9, 0xe7, 0x1a, 0xd6, 0x96, 0xec, + 0x21, 0x7c, 0x8e, 0x69, 0x72, 0x88, 0x40, 0x93, 0xcb, 0xe8, 0x45, 0x18, 0xdd, 0x25, 0x2e, 0x2f, + 0x3e, 0x23, 0x1c, 0x93, 0x77, 0x87, 0xbb, 0x02, 0x24, 0x50, 0x7d, 0x04, 0xf5, 0x97, 0x39, 0x28, + 0x4b, 0x07, 0x9a, 0x9a, 0xd1, 0x46, 0xf7, 0x22, 0x01, 0x25, 0x3c, 0xf1, 0xd2, 0x10, 0x9e, 0x08, + 0x73, 0x7d, 0x40, 0x04, 0x12, 0x28, 0xb3, 0xce, 0xe8, 0xb9, 0xa2, 0xbd, 0x08, 0x07, 0xd4, 0x33, + 0x06, 0x9e, 0x24, 0x6b, 0x9c, 0x94, 0x02, 0xca, 0x21, 0x8c, 0xe2, 0x28, 0x5f, 0x74, 0x3f, 0x70, + 0xf1, 0x30, 0x0d, 0x9e, 0x6d, 0x3e, 0x9b, 0x77, 0x3f, 0x52, 0xa0, 0x92, 0x46, 0x14, 0xcb, 0x47, + 0xe5, 0x50, 0xf9, 0x98, 0x3b, 0xba, 0x7c, 0xfc, 0xad, 0x12, 0xf1, 0x3d, 0xa5, 0xe8, 0x7b, 0x50, + 0x62, 0x03, 0x3e, 0x9f, 0xd7, 0x45, 0xef, 0x79, 0x39, 0xdb, 0x71, 0xe0, 0xf6, 0xc6, 0xf7, 0x89, + 0xee, 0xdd, 0x22, 0x9e, 0x16, 0xf6, 0xb9, 0x10, 0x86, 0x03, 0xae, 0xe8, 0x36, 0x14, 0xa8, 0x43, + 0xf4, 0x61, 0x7a, 0x3c, 0x57, 0xad, 0xe9, 0x10, 0x3d, 0xac, 0xd7, 0xec, 0x1f, 0xe6, 0x8c, 0xd4, + 0x9f, 0x46, 0x9d, 0x41, 0x69, 0xdc, 0x19, 0x69, 0x26, 0x56, 0x8e, 0xce, 0xc4, 0xbf, 0x09, 0x4a, + 0x01, 0xd7, 0xef, 0xa6, 0x41, 0x3d, 0xf4, 0x76, 0x9f, 0x99, 0xeb, 0xd9, 0xcc, 0xcc, 0xa8, 0xb9, + 0x91, 0x83, 0x2c, 0xf3, 0x21, 0x11, 0x13, 0xaf, 0xc2, 0x88, 0xe1, 0x91, 0xb6, 0x9f, 0x5f, 0x17, + 0x33, 0xdb, 0x38, 0x1c, 0x1c, 0x56, 0x18, 0x3d, 0x16, 0x6c, 0xd4, 0x47, 0xf1, 0x1d, 0x30, 0xdb, + 0xa3, 0xef, 0xc0, 0x18, 0x95, 0xc3, 0x8e, 0x5f, 0x25, 0x66, 0xb3, 0xc8, 0x09, 0xc6, 0xd5, 0x29, + 0x29, 0x6a, 0xcc, 0x87, 0x50, 0x1c, 0x72, 0x8c, 0x64, 0x70, 0x6e, 0xa8, 0x0c, 0x4e, 0xf8, 0x3f, + 0x35, 0x83, 0x5d, 0x18, 0xe4, 0x40, 0xf4, 0x6d, 0x28, 0xda, 0x8e, 0xf6, 0x4e, 0x30, 0x78, 0x3d, + 0xe1, 0x64, 0x72, 0x9b, 0xe3, 0x0e, 0x0a, 0x13, 0x60, 0x32, 0xc5, 0x32, 0x96, 0x2c, 0xd5, 0xf7, + 0x15, 0x98, 0x4c, 0x16, 0xb3, 0x21, 0xaa, 0xc5, 0x1a, 0x4c, 0xb4, 0x35, 0x4f, 0xdf, 0x0e, 0x1a, + 0x8a, 0x3c, 0xff, 0xcf, 0xf4, 0xba, 0xb5, 0x89, 0x5b, 0xb1, 0x95, 0xfd, 0x6e, 0x0d, 0x5d, 0xeb, + 0x98, 0xe6, 0x5e, 0xfc, 0x2c, 0x94, 0xa0, 0x57, 0x3f, 0xcc, 0x05, 0x99, 0xd3, 0x77, 0xb8, 0x61, + 0x13, 0xac, 0x1e, 0x8c, 0x73, 0xc9, 0x09, 0x36, 0x1c, 0xf4, 0x70, 0x04, 0x0b, 0xb9, 0x7d, 0x03, + 0xe3, 0xd2, 0xe1, 0x8e, 0x56, 0xcf, 0xd9, 0xf8, 0xf8, 0xd7, 0x02, 0x8c, 0xc7, 0x9a, 0x5c, 0x86, + 0x31, 0x72, 0x01, 0x4e, 0xb4, 0xc2, 0xa8, 0xe4, 0xe7, 0x3e, 0xe1, 0xaf, 0xcf, 0x4a, 0xe4, 0x68, + 0x4a, 0x71, 0xba, 0x24, 0x7e, 0x3c, 0xc7, 0xf2, 0x4f, 0x3d, 0xc7, 0xee, 0xc2, 0x84, 0x16, 0x8c, + 0x35, 0xb7, 0xec, 0x96, 0x7f, 0x30, 0xad, 0x4b, 0xaa, 0x89, 0x85, 0xd8, 0xea, 0x7e, 0xb7, 0xf6, + 0x99, 0xe4, 0x30, 0xc4, 0xe0, 0x38, 0xc1, 0x05, 0x5d, 0x80, 0x11, 0xee, 0x1d, 0x3e, 0x79, 0xe4, + 0xc3, 0x9a, 0xc2, 0x0d, 0x8b, 0xc5, 0x1a, 0xba, 0x0c, 0x65, 0xad, 0xd5, 0x36, 0xac, 0x05, 0x5d, + 0x27, 0xd4, 0x3f, 0x90, 0xf2, 0x71, 0x66, 0x21, 0x04, 0xe3, 0x28, 0x0e, 0xb2, 0x60, 0x62, 0xd3, + 0x70, 0xa9, 0xb7, 0xb0, 0xab, 0x19, 0xa6, 0xb6, 0x61, 0x12, 0x79, 0x3c, 0xcd, 0x34, 0x3f, 0x34, + 0x3b, 0x1b, 0xfe, 0x80, 0x72, 0xda, 0xdf, 0xdf, 0xb5, 0x18, 0x37, 0x9c, 0xe0, 0xce, 0x86, 0x15, + 0xcf, 0x36, 0x89, 0xc8, 0x68, 0x5a, 0x29, 0x65, 0x17, 0xb6, 0x1e, 0x90, 0x85, 0xc3, 0x4a, 0x08, + 0xa3, 0x38, 0xca, 0x57, 0xfd, 0x4b, 0x70, 0x46, 0x48, 0x99, 0x65, 0xd1, 0x45, 0x36, 0x19, 0xf3, + 0x25, 0x19, 0x6f, 0x91, 0xe1, 0x96, 0x83, 0xb1, 0xbf, 0x1e, 0xb9, 0x42, 0xcc, 0x65, 0xba, 0x42, + 0xcc, 0x67, 0xb8, 0x42, 0x2c, 0x1c, 0x78, 0x85, 0x98, 0x70, 0xe4, 0x48, 0x06, 0x47, 0x26, 0x0c, + 0x5b, 0x7c, 0x46, 0x86, 0x7d, 0x1b, 0x26, 0x12, 0xa7, 0xf2, 0x1b, 0x90, 0xd7, 0x89, 0x29, 0x6b, + 0xfb, 0x13, 0x2e, 0x0d, 0xfb, 0xce, 0xf4, 0x8d, 0xd1, 0x5e, 0xb7, 0x96, 0x5f, 0x5c, 0xbe, 0x89, + 0x19, 0x13, 0xf5, 0xd7, 0x79, 0xbf, 0x9a, 0x87, 0xa1, 0xf5, 0x69, 0x59, 0xf8, 0x5f, 0xcb, 0x42, + 0x22, 0x34, 0x46, 0x9f, 0x51, 0x68, 0xfc, 0x3b, 0x18, 0x7b, 0xf9, 0x3d, 0x15, 0x7a, 0x21, 0xd2, + 0x33, 0x1a, 0x65, 0x49, 0x9e, 0x7f, 0x93, 0xec, 0x89, 0x06, 0x72, 0x21, 0xda, 0x40, 0xc6, 0x06, + 0x5f, 0xaf, 0xa0, 0xab, 0x50, 0x24, 0x9b, 0x9b, 0x44, 0xf7, 0x64, 0x52, 0xf9, 0x17, 0xa3, 0xc5, + 0x65, 0x0e, 0xdd, 0xef, 0xd6, 0xa6, 0x22, 0x22, 0x05, 0x10, 0x4b, 0x12, 0xf4, 0x0d, 0x18, 0xf3, + 0x8c, 0x36, 0x59, 0x68, 0xb5, 0x48, 0x8b, 0xdb, 0xbb, 0x3c, 0xff, 0x62, 0xb6, 0x89, 0x70, 0xdd, + 0x68, 0x13, 0x71, 0x58, 0x5c, 0xf7, 0x19, 0xe0, 0x90, 0x97, 0xfa, 0x30, 0x98, 0xdd, 0xb8, 0x58, + 0xdc, 0x31, 0xc9, 0x11, 0x0c, 0xf9, 0xcd, 0xd8, 0x90, 0x7f, 0x39, 0xf3, 0xfd, 0x21, 0x53, 0x2f, + 0x75, 0xd0, 0xff, 0x48, 0xf1, 0x87, 0xb6, 0x00, 0xf7, 0x08, 0x86, 0x69, 0x1c, 0x1f, 0xa6, 0x2f, + 0x0d, 0xb5, 0x97, 0x94, 0x81, 0xfa, 0xe3, 0xfe, 0x9d, 0xf0, 0xa1, 0xba, 0x0d, 0x13, 0xad, 0x58, + 0xaa, 0x0e, 0x73, 0x4e, 0xe1, 0xac, 0x82, 0x1c, 0x47, 0x2c, 0x53, 0xe3, 0x79, 0x8f, 0x13, 0xcc, + 0xd9, 0x39, 0x81, 0x5f, 0xcf, 0x66, 0xbb, 0xe9, 0x8a, 0x5e, 0xf3, 0x06, 0xdb, 0x12, 0xfa, 0x0b, + 0x36, 0xea, 0x4f, 0x72, 0xb1, 0x6d, 0x05, 0x72, 0xbe, 0xd6, 0x5f, 0xf3, 0x44, 0xa6, 0x9d, 0xcc, + 0x54, 0xef, 0xd4, 0x44, 0x4f, 0x83, 0x01, 0xfd, 0xec, 0x6c, 0xac, 0x9f, 0x95, 0x12, 0xbd, 0x4c, + 0x4d, 0xf4, 0x32, 0x18, 0xd0, 0xc7, 0x62, 0x55, 0x75, 0xe4, 0x69, 0x57, 0x55, 0xf5, 0x67, 0x39, + 0xbf, 0x5d, 0x84, 0x45, 0xe9, 0x49, 0x65, 0xe7, 0x0d, 0x28, 0xd9, 0x0e, 0xc3, 0xb5, 0xfd, 0xad, + 0xcf, 0xfa, 0x81, 0x7a, 0x5b, 0xc2, 0xf7, 0xbb, 0xb5, 0x4a, 0x92, 0xad, 0xbf, 0x86, 0x03, 0xea, + 0xb0, 0x80, 0xe5, 0x33, 0x15, 0xb0, 0xc2, 0xf0, 0x05, 0x6c, 0x11, 0xa6, 0xc2, 0x02, 0xdb, 0x24, + 0xba, 0x6d, 0xb5, 0xa8, 0xac, 0xf4, 0xa7, 0x7a, 0xdd, 0xda, 0xd4, 0x7a, 0x72, 0x11, 0xf7, 0xe3, + 0xab, 0xbf, 0x50, 0x60, 0xaa, 0xef, 0x63, 0x1d, 0xba, 0x0a, 0xe3, 0x06, 0x9b, 0xc8, 0x37, 0x35, + 0x9d, 0x44, 0x82, 0xe7, 0x94, 0x54, 0x6f, 0x7c, 0x25, 0xba, 0x88, 0xe3, 0xb8, 0xe8, 0x0c, 0xe4, + 0x0d, 0xc7, 0xbf, 0x18, 0xe5, 0x1d, 0x7c, 0x65, 0x8d, 0x62, 0x06, 0x63, 0xad, 0x78, 0x5b, 0x73, + 0x5b, 0x0f, 0x34, 0x97, 0xd5, 0x4a, 0x97, 0x4d, 0x2f, 0xf9, 0x78, 0x2b, 0x7e, 0x23, 0xbe, 0x8c, + 0x93, 0xf8, 0xea, 0x87, 0x0a, 0x9c, 0x49, 0x3d, 0x04, 0x66, 0xfe, 0x9e, 0xab, 0x01, 0x38, 0x9a, + 0xab, 0xb5, 0x89, 0x3c, 0x38, 0x1d, 0xe2, 0x33, 0x69, 0x50, 0x8e, 0xd7, 0x02, 0x46, 0x38, 0xc2, + 0x54, 0xfd, 0x20, 0x07, 0xe3, 0x58, 0x46, 0xb0, 0xb8, 0xe5, 0x7b, 0xf6, 0x4d, 0xe0, 0x4e, 0xac, + 0x09, 0x3c, 0x61, 0xdc, 0x8a, 0x29, 0x97, 0xd6, 0x02, 0xd0, 0x3d, 0x28, 0x52, 0xfe, 0xad, 0x3c, + 0xdb, 0x9d, 0x75, 0x9c, 0x29, 0x27, 0x0c, 0x9d, 0x20, 0xfe, 0x63, 0xc9, 0x50, 0xed, 0x29, 0x50, + 0x8d, 0xe1, 0xcb, 0x8f, 0x7a, 0x2e, 0x26, 0x9b, 0xc4, 0x25, 0x96, 0x4e, 0xd0, 0x2c, 0x94, 0x34, + 0xc7, 0xb8, 0xee, 0xda, 0x1d, 0x47, 0x7a, 0x34, 0x68, 0x1c, 0x0b, 0x6b, 0x2b, 0x1c, 0x8e, 0x03, + 0x0c, 0x86, 0xed, 0x6b, 0x24, 0xe3, 0x2a, 0x72, 0x33, 0x2a, 0xe0, 0x38, 0xc0, 0x08, 0x26, 0xc7, + 0x42, 0xea, 0xe4, 0xd8, 0x80, 0x7c, 0xc7, 0x68, 0xc9, 0xeb, 0xdc, 0x97, 0xfd, 0x62, 0xf1, 0xd6, + 0xca, 0xd2, 0x7e, 0xb7, 0x76, 0x3e, 0xed, 0x2d, 0x82, 0xb7, 0xe7, 0x10, 0x5a, 0x7f, 0x6b, 0x65, + 0x09, 0x33, 0x62, 0xf5, 0x77, 0x0a, 0x4c, 0xc5, 0x36, 0x79, 0x04, 0x0d, 0x74, 0x2d, 0xde, 0x40, + 0x5f, 0x1a, 0xc2, 0x65, 0x29, 0xed, 0xd3, 0x48, 0x6c, 0x82, 0xf7, 0xce, 0xf5, 0xe4, 0xf7, 0xf9, + 0x8b, 0x99, 0x2f, 0x7d, 0xd3, 0x3f, 0xca, 0xab, 0x7f, 0xc8, 0xc1, 0xc9, 0x01, 0x51, 0x84, 0xee, + 0x03, 0x84, 0xe3, 0xed, 0x00, 0xa3, 0x0d, 0x10, 0xd8, 0xf7, 0x89, 0x62, 0x82, 0x7f, 0x35, 0x0f, + 0xa1, 0x11, 0x8e, 0x88, 0x42, 0xd9, 0x25, 0x94, 0xb8, 0xbb, 0xa4, 0x75, 0x8d, 0x57, 0x7f, 0x66, + 0xba, 0xaf, 0x0e, 0x61, 0xba, 0xbe, 0xe8, 0x0d, 0xa7, 0x62, 0x1c, 0x32, 0xc6, 0x51, 0x29, 0xe8, + 0x7e, 0x68, 0x42, 0xf1, 0x14, 0xe4, 0x4a, 0xa6, 0x1d, 0xc5, 0x5f, 0xb1, 0x1c, 0x60, 0xcc, 0x8f, + 0x15, 0x38, 0x15, 0x53, 0x72, 0x9d, 0xb4, 0x1d, 0x53, 0xf3, 0x8e, 0x62, 0x22, 0xbd, 0x17, 0x2b, + 0x46, 0xaf, 0x0d, 0x61, 0x49, 0x5f, 0xc9, 0xd4, 0xb9, 0xf4, 0xcf, 0x0a, 0x9c, 0x19, 0x48, 0x71, + 0x04, 0xc9, 0xf5, 0xcd, 0x78, 0x72, 0x5d, 0x39, 0xc4, 0xbe, 0xd2, 0x2f, 0x7d, 0xcf, 0xa4, 0xda, + 0xe1, 0xff, 0xb2, 0x7b, 0xa8, 0xbf, 0x52, 0xe0, 0xb8, 0x8f, 0xc9, 0xa6, 0xc3, 0x0c, 0xc7, 0xf5, + 0x79, 0x00, 0xf9, 0x7e, 0xcb, 0xff, 0x30, 0x93, 0x0f, 0xf5, 0xbe, 0x1e, 0xac, 0xe0, 0x08, 0x16, + 0xba, 0x01, 0xc8, 0xd7, 0xb0, 0x69, 0xfa, 0xd7, 0x9b, 0xbc, 0x05, 0xe4, 0x1b, 0xd3, 0x92, 0x16, + 0xe1, 0x3e, 0x0c, 0x3c, 0x80, 0x4a, 0xfd, 0xbd, 0x12, 0xf6, 0x6d, 0x0e, 0x7e, 0x5e, 0x2d, 0xcf, + 0x95, 0x4b, 0xb5, 0x7c, 0xb4, 0xef, 0x70, 0xcc, 0xe7, 0xb6, 0xef, 0x70, 0xed, 0x52, 0x52, 0xe2, + 0x4f, 0x85, 0xc4, 0x2e, 0x78, 0x2a, 0x64, 0x9d, 0xf2, 0x6e, 0x46, 0x5e, 0xed, 0xc5, 0x4f, 0xf7, + 0x07, 0xa8, 0xc3, 0xc2, 0x74, 0xe0, 0xf5, 0xdc, 0x6c, 0xe4, 0x3d, 0x51, 0x62, 0xba, 0xc8, 0xf0, + 0xa6, 0xa8, 0xf0, 0x94, 0xde, 0x14, 0xcd, 0x46, 0xde, 0x14, 0x89, 0x9b, 0xbf, 0x70, 0x22, 0xea, + 0x7f, 0x57, 0x74, 0x3b, 0xec, 0x2f, 0xe2, 0xce, 0xef, 0xf3, 0x59, 0x5a, 0xf4, 0x01, 0x4f, 0xe6, + 0x30, 0x9c, 0x76, 0x88, 0x2b, 0xc0, 0xa1, 0x96, 0x2c, 0x53, 0x47, 0xb9, 0x32, 0xd3, 0xbd, 0x6e, + 0xed, 0xf4, 0xda, 0x40, 0x0c, 0x9c, 0x42, 0x89, 0xb6, 0x61, 0x82, 0x6e, 0x6b, 0x2e, 0x69, 0x05, + 0x8f, 0xc4, 0xc4, 0xc5, 0xef, 0x4c, 0xd6, 0xa7, 0x2f, 0xe1, 0xfd, 0x72, 0x33, 0xc6, 0x07, 0x27, + 0xf8, 0x36, 0x1a, 0x0f, 0x1f, 0x57, 0x8f, 0x3d, 0x7a, 0x5c, 0x3d, 0xf6, 0xc9, 0xe3, 0xea, 0xb1, + 0xf7, 0x7a, 0x55, 0xe5, 0x61, 0xaf, 0xaa, 0x3c, 0xea, 0x55, 0x95, 0x4f, 0x7a, 0x55, 0xe5, 0x1f, + 0xbd, 0xaa, 0xf2, 0xe3, 0x7f, 0x56, 0x8f, 0x7d, 0xeb, 0xec, 0x41, 0x4f, 0x74, 0xff, 0x1b, 0x00, + 0x00, 0xff, 0xff, 0xa5, 0x57, 0x37, 0xad, 0xc1, 0x2b, 0x00, 0x00, } func (m *AllocatedDeviceStatus) Marshal() (dAtA []byte, err error) { @@ -1178,16 +1509,18 @@ func (m *AllocatedDeviceStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x32 } - { - size, err := m.Data.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err + if m.Data != nil { + { + size, err := m.Data.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x2a } - i-- - dAtA[i] = 0x2a if len(m.Conditions) > 0 { for iNdEx := len(m.Conditions) - 1; iNdEx >= 0; iNdEx-- { { @@ -1285,17 +1618,10 @@ func (m *BasicDevice) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if len(m.Capacity) > 0 { - keysForCapacity := make([]string, 0, len(m.Capacity)) - for k := range m.Capacity { - keysForCapacity = append(keysForCapacity, string(k)) - } - github_com_gogo_protobuf_sortkeys.Strings(keysForCapacity) - for iNdEx := len(keysForCapacity) - 1; iNdEx >= 0; iNdEx-- { - v := m.Capacity[QualifiedName(keysForCapacity[iNdEx])] - baseI := i + if len(m.Taints) > 0 { + for iNdEx := len(m.Taints) - 1; iNdEx >= 0; iNdEx-- { { - size, err := (&v).MarshalToSizedBuffer(dAtA[:i]) + size, err := m.Taints[iNdEx].MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -1303,21 +1629,85 @@ func (m *BasicDevice) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenerated(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x12 - i -= len(keysForCapacity[iNdEx]) - copy(dAtA[i:], keysForCapacity[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(keysForCapacity[iNdEx]))) - i-- - dAtA[i] = 0xa - i = encodeVarintGenerated(dAtA, i, uint64(baseI-i)) - i-- - dAtA[i] = 0x12 + dAtA[i] = 0x3a } } - if len(m.Attributes) > 0 { - keysForAttributes := make([]string, 0, len(m.Attributes)) - for k := range m.Attributes { - keysForAttributes = append(keysForAttributes, string(k)) + if m.AllNodes != nil { + i-- + if *m.AllNodes { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x30 + } + if m.NodeSelector != nil { + { + size, err := m.NodeSelector.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + if m.NodeName != nil { + i -= len(*m.NodeName) + copy(dAtA[i:], *m.NodeName) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.NodeName))) + i-- + dAtA[i] = 0x22 + } + if len(m.ConsumesCounters) > 0 { + for iNdEx := len(m.ConsumesCounters) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ConsumesCounters[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if len(m.Capacity) > 0 { + keysForCapacity := make([]string, 0, len(m.Capacity)) + for k := range m.Capacity { + keysForCapacity = append(keysForCapacity, string(k)) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForCapacity) + for iNdEx := len(keysForCapacity) - 1; iNdEx >= 0; iNdEx-- { + v := m.Capacity[QualifiedName(keysForCapacity[iNdEx])] + baseI := i + { + size, err := (&v).MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + i -= len(keysForCapacity[iNdEx]) + copy(dAtA[i:], keysForCapacity[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(keysForCapacity[iNdEx]))) + i-- + dAtA[i] = 0xa + i = encodeVarintGenerated(dAtA, i, uint64(baseI-i)) + i-- + dAtA[i] = 0x12 + } + } + if len(m.Attributes) > 0 { + keysForAttributes := make([]string, 0, len(m.Attributes)) + for k := range m.Attributes { + keysForAttributes = append(keysForAttributes, string(k)) } github_com_gogo_protobuf_sortkeys.Strings(keysForAttributes) for iNdEx := len(keysForAttributes) - 1; iNdEx >= 0; iNdEx-- { @@ -1374,6 +1764,96 @@ func (m *CELDeviceSelector) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *Counter) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Counter) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Counter) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Value.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *CounterSet) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *CounterSet) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *CounterSet) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Counters) > 0 { + keysForCounters := make([]string, 0, len(m.Counters)) + for k := range m.Counters { + keysForCounters = append(keysForCounters, string(k)) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForCounters) + for iNdEx := len(keysForCounters) - 1; iNdEx >= 0; iNdEx-- { + v := m.Counters[string(keysForCounters[iNdEx])] + baseI := i + { + size, err := (&v).MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + i -= len(keysForCounters[iNdEx]) + copy(dAtA[i:], keysForCounters[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(keysForCounters[iNdEx]))) + i-- + dAtA[i] = 0xa + i = encodeVarintGenerated(dAtA, i, uint64(baseI-i)) + i-- + dAtA[i] = 0x12 + } + } + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *Device) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1919,6 +2399,63 @@ func (m *DeviceConstraint) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *DeviceCounterConsumption) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *DeviceCounterConsumption) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *DeviceCounterConsumption) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Counters) > 0 { + keysForCounters := make([]string, 0, len(m.Counters)) + for k := range m.Counters { + keysForCounters = append(keysForCounters, string(k)) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForCounters) + for iNdEx := len(keysForCounters) - 1; iNdEx >= 0; iNdEx-- { + v := m.Counters[string(keysForCounters[iNdEx])] + baseI := i + { + size, err := (&v).MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + i -= len(keysForCounters[iNdEx]) + copy(dAtA[i:], keysForCounters[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(keysForCounters[iNdEx]))) + i-- + dAtA[i] = 0xa + i = encodeVarintGenerated(dAtA, i, uint64(baseI-i)) + i-- + dAtA[i] = 0x12 + } + } + i -= len(m.CounterSet) + copy(dAtA[i:], m.CounterSet) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.CounterSet))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *DeviceRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1939,6 +2476,34 @@ func (m *DeviceRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.Tolerations) > 0 { + for iNdEx := len(m.Tolerations) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Tolerations[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x42 + } + } + if len(m.FirstAvailable) > 0 { + for iNdEx := len(m.FirstAvailable) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.FirstAvailable[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x3a + } + } if m.AdminAccess != nil { i-- if *m.AdminAccess { @@ -2004,6 +2569,20 @@ func (m *DeviceRequestAllocationResult) MarshalToSizedBuffer(dAtA []byte) (int, _ = i var l int _ = l + if len(m.Tolerations) > 0 { + for iNdEx := len(m.Tolerations) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Tolerations[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + } + } if m.AdminAccess != nil { i-- if *m.AdminAccess { @@ -2072,7 +2651,7 @@ func (m *DeviceSelector) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *NetworkDeviceData) Marshal() (dAtA []byte, err error) { +func (m *DeviceSubRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -2082,77 +2661,66 @@ func (m *NetworkDeviceData) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *NetworkDeviceData) MarshalTo(dAtA []byte) (int, error) { +func (m *DeviceSubRequest) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *NetworkDeviceData) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *DeviceSubRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - i -= len(m.HardwareAddress) - copy(dAtA[i:], m.HardwareAddress) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.HardwareAddress))) - i-- - dAtA[i] = 0x1a - if len(m.IPs) > 0 { - for iNdEx := len(m.IPs) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.IPs[iNdEx]) - copy(dAtA[i:], m.IPs[iNdEx]) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.IPs[iNdEx]))) + if len(m.Tolerations) > 0 { + for iNdEx := len(m.Tolerations) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Tolerations[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } i-- - dAtA[i] = 0x12 + dAtA[i] = 0x3a } } - i -= len(m.InterfaceName) - copy(dAtA[i:], m.InterfaceName) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.InterfaceName))) + i = encodeVarintGenerated(dAtA, i, uint64(m.Count)) i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *OpaqueDeviceConfiguration) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *OpaqueDeviceConfiguration) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *OpaqueDeviceConfiguration) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - { - size, err := m.Parameters.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err + dAtA[i] = 0x28 + i -= len(m.AllocationMode) + copy(dAtA[i:], m.AllocationMode) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.AllocationMode))) + i-- + dAtA[i] = 0x22 + if len(m.Selectors) > 0 { + for iNdEx := len(m.Selectors) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Selectors[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) } + i -= len(m.DeviceClassName) + copy(dAtA[i:], m.DeviceClassName) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.DeviceClassName))) i-- dAtA[i] = 0x12 - i -= len(m.Driver) - copy(dAtA[i:], m.Driver) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Driver))) + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) i-- dAtA[i] = 0xa return len(dAtA) - i, nil } -func (m *ResourceClaim) Marshal() (dAtA []byte, err error) { +func (m *DeviceTaint) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -2162,50 +2730,47 @@ func (m *ResourceClaim) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *ResourceClaim) MarshalTo(dAtA []byte) (int, error) { +func (m *DeviceTaint) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ResourceClaim) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *DeviceTaint) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - { - size, err := m.Status.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err + if m.TimeAdded != nil { + { + size, err := m.TimeAdded.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x22 } + i -= len(m.Effect) + copy(dAtA[i:], m.Effect) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Effect))) i-- dAtA[i] = 0x1a - { - size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } + i -= len(m.Value) + copy(dAtA[i:], m.Value) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Value))) i-- dAtA[i] = 0x12 - { - size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } + i -= len(m.Key) + copy(dAtA[i:], m.Key) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Key))) i-- dAtA[i] = 0xa return len(dAtA) - i, nil } -func (m *ResourceClaimConsumerReference) Marshal() (dAtA []byte, err error) { +func (m *DeviceTaintRule) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -2215,40 +2780,40 @@ func (m *ResourceClaimConsumerReference) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *ResourceClaimConsumerReference) MarshalTo(dAtA []byte) (int, error) { +func (m *DeviceTaintRule) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ResourceClaimConsumerReference) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *DeviceTaintRule) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - i -= len(m.UID) - copy(dAtA[i:], m.UID) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.UID))) - i-- - dAtA[i] = 0x2a - i -= len(m.Name) - copy(dAtA[i:], m.Name) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) - i-- - dAtA[i] = 0x22 - i -= len(m.Resource) - copy(dAtA[i:], m.Resource) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Resource))) + { + size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } i-- - dAtA[i] = 0x1a - i -= len(m.APIGroup) - copy(dAtA[i:], m.APIGroup) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.APIGroup))) + dAtA[i] = 0x12 + { + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } i-- dAtA[i] = 0xa return len(dAtA) - i, nil } -func (m *ResourceClaimList) Marshal() (dAtA []byte, err error) { +func (m *DeviceTaintRuleList) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -2258,12 +2823,12 @@ func (m *ResourceClaimList) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *ResourceClaimList) MarshalTo(dAtA []byte) (int, error) { +func (m *DeviceTaintRuleList) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ResourceClaimList) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *DeviceTaintRuleList) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -2295,7 +2860,7 @@ func (m *ResourceClaimList) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *ResourceClaimSpec) Marshal() (dAtA []byte, err error) { +func (m *DeviceTaintRuleSpec) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -2305,18 +2870,18 @@ func (m *ResourceClaimSpec) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *ResourceClaimSpec) MarshalTo(dAtA []byte) (int, error) { +func (m *DeviceTaintRuleSpec) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ResourceClaimSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *DeviceTaintRuleSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l { - size, err := m.Devices.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.Taint.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -2324,11 +2889,23 @@ func (m *ResourceClaimSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenerated(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0xa + dAtA[i] = 0x12 + if m.DeviceSelector != nil { + { + size, err := m.DeviceSelector.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } return len(dAtA) - i, nil } -func (m *ResourceClaimStatus) Marshal() (dAtA []byte, err error) { +func (m *DeviceTaintSelector) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -2338,20 +2915,20 @@ func (m *ResourceClaimStatus) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *ResourceClaimStatus) MarshalTo(dAtA []byte) (int, error) { +func (m *DeviceTaintSelector) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ResourceClaimStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *DeviceTaintSelector) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if len(m.Devices) > 0 { - for iNdEx := len(m.Devices) - 1; iNdEx >= 0; iNdEx-- { + if len(m.Selectors) > 0 { + for iNdEx := len(m.Selectors) - 1; iNdEx >= 0; iNdEx-- { { - size, err := m.Devices[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + size, err := m.Selectors[iNdEx].MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -2359,39 +2936,41 @@ func (m *ResourceClaimStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenerated(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x22 + dAtA[i] = 0x2a } } - if len(m.ReservedFor) > 0 { - for iNdEx := len(m.ReservedFor) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.ReservedFor[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } + if m.Device != nil { + i -= len(*m.Device) + copy(dAtA[i:], *m.Device) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.Device))) + i-- + dAtA[i] = 0x22 } - if m.Allocation != nil { - { - size, err := m.Allocation.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } + if m.Pool != nil { + i -= len(*m.Pool) + copy(dAtA[i:], *m.Pool) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.Pool))) + i-- + dAtA[i] = 0x1a + } + if m.Driver != nil { + i -= len(*m.Driver) + copy(dAtA[i:], *m.Driver) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.Driver))) + i-- + dAtA[i] = 0x12 + } + if m.DeviceClassName != nil { + i -= len(*m.DeviceClassName) + copy(dAtA[i:], *m.DeviceClassName) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.DeviceClassName))) i-- dAtA[i] = 0xa } return len(dAtA) - i, nil } -func (m *ResourceClaimTemplate) Marshal() (dAtA []byte, err error) { +func (m *DeviceToleration) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -2401,40 +2980,45 @@ func (m *ResourceClaimTemplate) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *ResourceClaimTemplate) MarshalTo(dAtA []byte) (int, error) { +func (m *DeviceToleration) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ResourceClaimTemplate) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *DeviceToleration) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - { - size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) + if m.TolerationSeconds != nil { + i = encodeVarintGenerated(dAtA, i, uint64(*m.TolerationSeconds)) + i-- + dAtA[i] = 0x28 } + i -= len(m.Effect) + copy(dAtA[i:], m.Effect) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Effect))) + i-- + dAtA[i] = 0x22 + i -= len(m.Value) + copy(dAtA[i:], m.Value) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Value))) + i-- + dAtA[i] = 0x1a + i -= len(m.Operator) + copy(dAtA[i:], m.Operator) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Operator))) i-- dAtA[i] = 0x12 - { - size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } + i -= len(m.Key) + copy(dAtA[i:], m.Key) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Key))) i-- dAtA[i] = 0xa return len(dAtA) - i, nil } -func (m *ResourceClaimTemplateList) Marshal() (dAtA []byte, err error) { +func (m *NetworkDeviceData) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -2444,44 +3028,39 @@ func (m *ResourceClaimTemplateList) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *ResourceClaimTemplateList) MarshalTo(dAtA []byte) (int, error) { +func (m *NetworkDeviceData) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ResourceClaimTemplateList) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *NetworkDeviceData) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if len(m.Items) > 0 { - for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } + i -= len(m.HardwareAddress) + copy(dAtA[i:], m.HardwareAddress) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.HardwareAddress))) + i-- + dAtA[i] = 0x1a + if len(m.IPs) > 0 { + for iNdEx := len(m.IPs) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.IPs[iNdEx]) + copy(dAtA[i:], m.IPs[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.IPs[iNdEx]))) i-- dAtA[i] = 0x12 } } - { - size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } + i -= len(m.InterfaceName) + copy(dAtA[i:], m.InterfaceName) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.InterfaceName))) i-- dAtA[i] = 0xa return len(dAtA) - i, nil } -func (m *ResourceClaimTemplateSpec) Marshal() (dAtA []byte, err error) { +func (m *OpaqueDeviceConfiguration) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -2491,18 +3070,18 @@ func (m *ResourceClaimTemplateSpec) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *ResourceClaimTemplateSpec) MarshalTo(dAtA []byte) (int, error) { +func (m *OpaqueDeviceConfiguration) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ResourceClaimTemplateSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *OpaqueDeviceConfiguration) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l { - size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.Parameters.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -2511,20 +3090,15 @@ func (m *ResourceClaimTemplateSpec) MarshalToSizedBuffer(dAtA []byte) (int, erro } i-- dAtA[i] = 0x12 - { - size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } + i -= len(m.Driver) + copy(dAtA[i:], m.Driver) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Driver))) i-- dAtA[i] = 0xa return len(dAtA) - i, nil } -func (m *ResourcePool) Marshal() (dAtA []byte, err error) { +func (m *ResourceClaim) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -2534,31 +3108,50 @@ func (m *ResourcePool) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *ResourcePool) MarshalTo(dAtA []byte) (int, error) { +func (m *ResourceClaim) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ResourcePool) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *ResourceClaim) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - i = encodeVarintGenerated(dAtA, i, uint64(m.ResourceSliceCount)) - i-- - dAtA[i] = 0x18 - i = encodeVarintGenerated(dAtA, i, uint64(m.Generation)) - i-- - dAtA[i] = 0x10 - i -= len(m.Name) - copy(dAtA[i:], m.Name) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + { + size, err := m.Status.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + { + size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } i-- dAtA[i] = 0xa return len(dAtA) - i, nil } -func (m *ResourceSlice) Marshal() (dAtA []byte, err error) { +func (m *ResourceClaimConsumerReference) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -2568,40 +3161,40 @@ func (m *ResourceSlice) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *ResourceSlice) MarshalTo(dAtA []byte) (int, error) { +func (m *ResourceClaimConsumerReference) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ResourceSlice) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *ResourceClaimConsumerReference) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - { - size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } + i -= len(m.UID) + copy(dAtA[i:], m.UID) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.UID))) i-- - dAtA[i] = 0x12 - { - size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } + dAtA[i] = 0x2a + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0x22 + i -= len(m.Resource) + copy(dAtA[i:], m.Resource) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Resource))) + i-- + dAtA[i] = 0x1a + i -= len(m.APIGroup) + copy(dAtA[i:], m.APIGroup) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.APIGroup))) i-- dAtA[i] = 0xa return len(dAtA) - i, nil } -func (m *ResourceSliceList) Marshal() (dAtA []byte, err error) { +func (m *ResourceClaimList) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -2611,12 +3204,12 @@ func (m *ResourceSliceList) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *ResourceSliceList) MarshalTo(dAtA []byte) (int, error) { +func (m *ResourceClaimList) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ResourceSliceList) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *ResourceClaimList) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -2648,7 +3241,7 @@ func (m *ResourceSliceList) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *ResourceSliceSpec) Marshal() (dAtA []byte, err error) { +func (m *ResourceClaimSpec) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -2658,12 +3251,45 @@ func (m *ResourceSliceSpec) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *ResourceSliceSpec) MarshalTo(dAtA []byte) (int, error) { +func (m *ResourceClaimSpec) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ResourceSliceSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *ResourceClaimSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Devices.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ResourceClaimStatus) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ResourceClaimStatus) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResourceClaimStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -2679,20 +3305,26 @@ func (m *ResourceSliceSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenerated(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x32 + dAtA[i] = 0x22 } } - i-- - if m.AllNodes { - dAtA[i] = 1 - } else { - dAtA[i] = 0 + if len(m.ReservedFor) > 0 { + for iNdEx := len(m.ReservedFor) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ReservedFor[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } } - i-- - dAtA[i] = 0x28 - if m.NodeSelector != nil { + if m.Allocation != nil { { - size, err := m.NodeSelector.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.Allocation.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -2700,15 +3332,33 @@ func (m *ResourceSliceSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenerated(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x22 + dAtA[i] = 0xa } - i -= len(m.NodeName) - copy(dAtA[i:], m.NodeName) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.NodeName))) - i-- - dAtA[i] = 0x1a + return len(dAtA) - i, nil +} + +func (m *ResourceClaimTemplate) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ResourceClaimTemplate) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResourceClaimTemplate) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l { - size, err := m.Pool.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -2717,282 +3367,432 @@ func (m *ResourceSliceSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { } i-- dAtA[i] = 0x12 - i -= len(m.Driver) - copy(dAtA[i:], m.Driver) - i = encodeVarintGenerated(dAtA, i, uint64(len(m.Driver))) + { + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } i-- dAtA[i] = 0xa return len(dAtA) - i, nil } -func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int { - offset -= sovGenerated(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ +func (m *ResourceClaimTemplateList) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - dAtA[offset] = uint8(v) - return base + return dAtA[:n], nil } -func (m *AllocatedDeviceStatus) Size() (n int) { - if m == nil { - return 0 - } + +func (m *ResourceClaimTemplateList) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResourceClaimTemplateList) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - l = len(m.Driver) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Pool) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Device) - n += 1 + l + sovGenerated(uint64(l)) - if len(m.Conditions) > 0 { - for _, e := range m.Conditions { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) + if len(m.Items) > 0 { + for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 } } - l = m.Data.Size() - n += 1 + l + sovGenerated(uint64(l)) - if m.NetworkData != nil { - l = m.NetworkData.Size() - n += 1 + l + sovGenerated(uint64(l)) + { + size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } - return n + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil } -func (m *AllocationResult) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.Devices.Size() - n += 1 + l + sovGenerated(uint64(l)) - if m.NodeSelector != nil { - l = m.NodeSelector.Size() - n += 1 + l + sovGenerated(uint64(l)) +func (m *ResourceClaimTemplateSpec) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - return n + return dAtA[:n], nil } -func (m *BasicDevice) Size() (n int) { - if m == nil { - return 0 - } +func (m *ResourceClaimTemplateSpec) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResourceClaimTemplateSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - if len(m.Attributes) > 0 { - for k, v := range m.Attributes { - _ = k - _ = v - l = v.Size() - mapEntrySize := 1 + len(k) + sovGenerated(uint64(len(k))) + 1 + l + sovGenerated(uint64(l)) - n += mapEntrySize + 1 + sovGenerated(uint64(mapEntrySize)) + { + size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } - if len(m.Capacity) > 0 { - for k, v := range m.Capacity { - _ = k - _ = v - l = v.Size() - mapEntrySize := 1 + len(k) + sovGenerated(uint64(len(k))) + 1 + l + sovGenerated(uint64(l)) - n += mapEntrySize + 1 + sovGenerated(uint64(mapEntrySize)) + i-- + dAtA[i] = 0x12 + { + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } - return n + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil } -func (m *CELDeviceSelector) Size() (n int) { - if m == nil { - return 0 +func (m *ResourcePool) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - var l int - _ = l - l = len(m.Expression) - n += 1 + l + sovGenerated(uint64(l)) - return n + return dAtA[:n], nil } -func (m *Device) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - if m.Basic != nil { - l = m.Basic.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - return n +func (m *ResourcePool) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *DeviceAllocationConfiguration) Size() (n int) { - if m == nil { - return 0 - } +func (m *ResourcePool) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - l = len(m.Source) - n += 1 + l + sovGenerated(uint64(l)) - if len(m.Requests) > 0 { - for _, s := range m.Requests { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } - } - l = m.DeviceConfiguration.Size() - n += 1 + l + sovGenerated(uint64(l)) - return n + i = encodeVarintGenerated(dAtA, i, uint64(m.ResourceSliceCount)) + i-- + dAtA[i] = 0x18 + i = encodeVarintGenerated(dAtA, i, uint64(m.Generation)) + i-- + dAtA[i] = 0x10 + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil } -func (m *DeviceAllocationResult) Size() (n int) { - if m == nil { - return 0 +func (m *ResourceSlice) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } + return dAtA[:n], nil +} + +func (m *ResourceSlice) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResourceSlice) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - if len(m.Results) > 0 { - for _, e := range m.Results { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) + { + size, err := m.Spec.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } - if len(m.Config) > 0 { - for _, e := range m.Config { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) + i-- + dAtA[i] = 0x12 + { + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } - return n + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil } -func (m *DeviceAttribute) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.IntValue != nil { - n += 1 + sovGenerated(uint64(*m.IntValue)) - } - if m.BoolValue != nil { - n += 2 - } - if m.StringValue != nil { - l = len(*m.StringValue) - n += 1 + l + sovGenerated(uint64(l)) - } - if m.VersionValue != nil { - l = len(*m.VersionValue) - n += 1 + l + sovGenerated(uint64(l)) +func (m *ResourceSliceList) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - return n + return dAtA[:n], nil } -func (m *DeviceClaim) Size() (n int) { - if m == nil { - return 0 - } +func (m *ResourceSliceList) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResourceSliceList) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - if len(m.Requests) > 0 { - for _, e := range m.Requests { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - } - if len(m.Constraints) > 0 { - for _, e := range m.Constraints { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) + if len(m.Items) > 0 { + for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 } } - if len(m.Config) > 0 { - for _, e := range m.Config { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) + { + size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) } - return n + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil } -func (m *DeviceClaimConfiguration) Size() (n int) { - if m == nil { - return 0 +func (m *ResourceSliceSpec) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - var l int - _ = l - if len(m.Requests) > 0 { - for _, s := range m.Requests { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) + return dAtA[:n], nil +} + +func (m *ResourceSliceSpec) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ResourceSliceSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.SharedCounters) > 0 { + for iNdEx := len(m.SharedCounters) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.SharedCounters[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x42 } } - l = m.DeviceConfiguration.Size() - n += 1 + l + sovGenerated(uint64(l)) - return n + if m.PerDeviceNodeSelection != nil { + i-- + if *m.PerDeviceNodeSelection { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x38 + } + if len(m.Devices) > 0 { + for iNdEx := len(m.Devices) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Devices[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + } + } + i-- + if m.AllNodes { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x28 + if m.NodeSelector != nil { + { + size, err := m.NodeSelector.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + i -= len(m.NodeName) + copy(dAtA[i:], m.NodeName) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.NodeName))) + i-- + dAtA[i] = 0x1a + { + size, err := m.Pool.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + i -= len(m.Driver) + copy(dAtA[i:], m.Driver) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Driver))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil } -func (m *DeviceClass) Size() (n int) { +func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int { + offset -= sovGenerated(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *AllocatedDeviceStatus) Size() (n int) { if m == nil { return 0 } var l int _ = l - l = m.ObjectMeta.Size() + l = len(m.Driver) n += 1 + l + sovGenerated(uint64(l)) - l = m.Spec.Size() + l = len(m.Pool) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Device) n += 1 + l + sovGenerated(uint64(l)) + if len(m.Conditions) > 0 { + for _, e := range m.Conditions { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + if m.Data != nil { + l = m.Data.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if m.NetworkData != nil { + l = m.NetworkData.Size() + n += 1 + l + sovGenerated(uint64(l)) + } return n } -func (m *DeviceClassConfiguration) Size() (n int) { +func (m *AllocationResult) Size() (n int) { if m == nil { return 0 } var l int _ = l - l = m.DeviceConfiguration.Size() + l = m.Devices.Size() n += 1 + l + sovGenerated(uint64(l)) + if m.NodeSelector != nil { + l = m.NodeSelector.Size() + n += 1 + l + sovGenerated(uint64(l)) + } return n } -func (m *DeviceClassList) Size() (n int) { +func (m *BasicDevice) Size() (n int) { if m == nil { return 0 } var l int _ = l - l = m.ListMeta.Size() - n += 1 + l + sovGenerated(uint64(l)) - if len(m.Items) > 0 { - for _, e := range m.Items { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) + if len(m.Attributes) > 0 { + for k, v := range m.Attributes { + _ = k + _ = v + l = v.Size() + mapEntrySize := 1 + len(k) + sovGenerated(uint64(len(k))) + 1 + l + sovGenerated(uint64(l)) + n += mapEntrySize + 1 + sovGenerated(uint64(mapEntrySize)) } } - return n -} - -func (m *DeviceClassSpec) Size() (n int) { - if m == nil { - return 0 + if len(m.Capacity) > 0 { + for k, v := range m.Capacity { + _ = k + _ = v + l = v.Size() + mapEntrySize := 1 + len(k) + sovGenerated(uint64(len(k))) + 1 + l + sovGenerated(uint64(l)) + n += mapEntrySize + 1 + sovGenerated(uint64(mapEntrySize)) + } } - var l int - _ = l - if len(m.Selectors) > 0 { - for _, e := range m.Selectors { + if len(m.ConsumesCounters) > 0 { + for _, e := range m.ConsumesCounters { l = e.Size() n += 1 + l + sovGenerated(uint64(l)) } } - if len(m.Config) > 0 { - for _, e := range m.Config { + if m.NodeName != nil { + l = len(*m.NodeName) + n += 1 + l + sovGenerated(uint64(l)) + } + if m.NodeSelector != nil { + l = m.NodeSelector.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if m.AllNodes != nil { + n += 2 + } + if len(m.Taints) > 0 { + for _, e := range m.Taints { l = e.Size() n += 1 + l + sovGenerated(uint64(l)) } @@ -3000,39 +3800,29 @@ func (m *DeviceClassSpec) Size() (n int) { return n } -func (m *DeviceConfiguration) Size() (n int) { +func (m *CELDeviceSelector) Size() (n int) { if m == nil { return 0 } var l int _ = l - if m.Opaque != nil { - l = m.Opaque.Size() - n += 1 + l + sovGenerated(uint64(l)) - } + l = len(m.Expression) + n += 1 + l + sovGenerated(uint64(l)) return n } -func (m *DeviceConstraint) Size() (n int) { +func (m *Counter) Size() (n int) { if m == nil { return 0 } var l int _ = l - if len(m.Requests) > 0 { - for _, s := range m.Requests { - l = len(s) - n += 1 + l + sovGenerated(uint64(l)) - } - } - if m.MatchAttribute != nil { - l = len(*m.MatchAttribute) - n += 1 + l + sovGenerated(uint64(l)) - } + l = m.Value.Size() + n += 1 + l + sovGenerated(uint64(l)) return n } -func (m *DeviceRequest) Size() (n int) { +func (m *CounterSet) Size() (n int) { if m == nil { return 0 } @@ -3040,89 +3830,141 @@ func (m *DeviceRequest) Size() (n int) { _ = l l = len(m.Name) n += 1 + l + sovGenerated(uint64(l)) - l = len(m.DeviceClassName) - n += 1 + l + sovGenerated(uint64(l)) - if len(m.Selectors) > 0 { - for _, e := range m.Selectors { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) + if len(m.Counters) > 0 { + for k, v := range m.Counters { + _ = k + _ = v + l = v.Size() + mapEntrySize := 1 + len(k) + sovGenerated(uint64(len(k))) + 1 + l + sovGenerated(uint64(l)) + n += mapEntrySize + 1 + sovGenerated(uint64(mapEntrySize)) } } - l = len(m.AllocationMode) - n += 1 + l + sovGenerated(uint64(l)) - n += 1 + sovGenerated(uint64(m.Count)) - if m.AdminAccess != nil { - n += 2 - } return n } -func (m *DeviceRequestAllocationResult) Size() (n int) { +func (m *Device) Size() (n int) { if m == nil { return 0 } var l int _ = l - l = len(m.Request) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Driver) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Pool) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Device) + l = len(m.Name) n += 1 + l + sovGenerated(uint64(l)) - if m.AdminAccess != nil { - n += 2 + if m.Basic != nil { + l = m.Basic.Size() + n += 1 + l + sovGenerated(uint64(l)) } return n } -func (m *DeviceSelector) Size() (n int) { +func (m *DeviceAllocationConfiguration) Size() (n int) { if m == nil { return 0 } var l int _ = l - if m.CEL != nil { - l = m.CEL.Size() - n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Source) + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Requests) > 0 { + for _, s := range m.Requests { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } } + l = m.DeviceConfiguration.Size() + n += 1 + l + sovGenerated(uint64(l)) return n } -func (m *NetworkDeviceData) Size() (n int) { +func (m *DeviceAllocationResult) Size() (n int) { if m == nil { return 0 } var l int _ = l - l = len(m.InterfaceName) - n += 1 + l + sovGenerated(uint64(l)) - if len(m.IPs) > 0 { - for _, s := range m.IPs { - l = len(s) + if len(m.Results) > 0 { + for _, e := range m.Results { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + if len(m.Config) > 0 { + for _, e := range m.Config { + l = e.Size() n += 1 + l + sovGenerated(uint64(l)) } } - l = len(m.HardwareAddress) - n += 1 + l + sovGenerated(uint64(l)) return n } -func (m *OpaqueDeviceConfiguration) Size() (n int) { +func (m *DeviceAttribute) Size() (n int) { if m == nil { return 0 } var l int _ = l - l = len(m.Driver) - n += 1 + l + sovGenerated(uint64(l)) - l = m.Parameters.Size() + if m.IntValue != nil { + n += 1 + sovGenerated(uint64(*m.IntValue)) + } + if m.BoolValue != nil { + n += 2 + } + if m.StringValue != nil { + l = len(*m.StringValue) + n += 1 + l + sovGenerated(uint64(l)) + } + if m.VersionValue != nil { + l = len(*m.VersionValue) + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + +func (m *DeviceClaim) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Requests) > 0 { + for _, e := range m.Requests { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + if len(m.Constraints) > 0 { + for _, e := range m.Constraints { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + if len(m.Config) > 0 { + for _, e := range m.Config { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *DeviceClaimConfiguration) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Requests) > 0 { + for _, s := range m.Requests { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } + l = m.DeviceConfiguration.Size() n += 1 + l + sovGenerated(uint64(l)) return n } -func (m *ResourceClaim) Size() (n int) { +func (m *DeviceClass) Size() (n int) { if m == nil { return 0 } @@ -3132,29 +3974,21 @@ func (m *ResourceClaim) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) l = m.Spec.Size() n += 1 + l + sovGenerated(uint64(l)) - l = m.Status.Size() - n += 1 + l + sovGenerated(uint64(l)) return n } -func (m *ResourceClaimConsumerReference) Size() (n int) { +func (m *DeviceClassConfiguration) Size() (n int) { if m == nil { return 0 } var l int _ = l - l = len(m.APIGroup) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Resource) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.Name) - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.UID) + l = m.DeviceConfiguration.Size() n += 1 + l + sovGenerated(uint64(l)) return n } -func (m *ResourceClaimList) Size() (n int) { +func (m *DeviceClassList) Size() (n int) { if m == nil { return 0 } @@ -3171,65 +4005,135 @@ func (m *ResourceClaimList) Size() (n int) { return n } -func (m *ResourceClaimSpec) Size() (n int) { +func (m *DeviceClassSpec) Size() (n int) { if m == nil { return 0 } var l int _ = l - l = m.Devices.Size() - n += 1 + l + sovGenerated(uint64(l)) + if len(m.Selectors) > 0 { + for _, e := range m.Selectors { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + if len(m.Config) > 0 { + for _, e := range m.Config { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } return n } -func (m *ResourceClaimStatus) Size() (n int) { +func (m *DeviceConfiguration) Size() (n int) { if m == nil { return 0 } var l int _ = l - if m.Allocation != nil { - l = m.Allocation.Size() + if m.Opaque != nil { + l = m.Opaque.Size() n += 1 + l + sovGenerated(uint64(l)) } - if len(m.ReservedFor) > 0 { - for _, e := range m.ReservedFor { - l = e.Size() + return n +} + +func (m *DeviceConstraint) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Requests) > 0 { + for _, s := range m.Requests { + l = len(s) n += 1 + l + sovGenerated(uint64(l)) } } - if len(m.Devices) > 0 { - for _, e := range m.Devices { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) + if m.MatchAttribute != nil { + l = len(*m.MatchAttribute) + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + +func (m *DeviceCounterConsumption) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.CounterSet) + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Counters) > 0 { + for k, v := range m.Counters { + _ = k + _ = v + l = v.Size() + mapEntrySize := 1 + len(k) + sovGenerated(uint64(len(k))) + 1 + l + sovGenerated(uint64(l)) + n += mapEntrySize + 1 + sovGenerated(uint64(mapEntrySize)) } } return n } -func (m *ResourceClaimTemplate) Size() (n int) { +func (m *DeviceRequest) Size() (n int) { if m == nil { return 0 } var l int _ = l - l = m.ObjectMeta.Size() + l = len(m.Name) n += 1 + l + sovGenerated(uint64(l)) - l = m.Spec.Size() + l = len(m.DeviceClassName) + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Selectors) > 0 { + for _, e := range m.Selectors { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + l = len(m.AllocationMode) n += 1 + l + sovGenerated(uint64(l)) + n += 1 + sovGenerated(uint64(m.Count)) + if m.AdminAccess != nil { + n += 2 + } + if len(m.FirstAvailable) > 0 { + for _, e := range m.FirstAvailable { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + if len(m.Tolerations) > 0 { + for _, e := range m.Tolerations { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } return n } -func (m *ResourceClaimTemplateList) Size() (n int) { +func (m *DeviceRequestAllocationResult) Size() (n int) { if m == nil { return 0 } var l int _ = l - l = m.ListMeta.Size() + l = len(m.Request) n += 1 + l + sovGenerated(uint64(l)) - if len(m.Items) > 0 { - for _, e := range m.Items { + l = len(m.Driver) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Pool) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Device) + n += 1 + l + sovGenerated(uint64(l)) + if m.AdminAccess != nil { + n += 2 + } + if len(m.Tolerations) > 0 { + for _, e := range m.Tolerations { l = e.Size() n += 1 + l + sovGenerated(uint64(l)) } @@ -3237,33 +4141,67 @@ func (m *ResourceClaimTemplateList) Size() (n int) { return n } -func (m *ResourceClaimTemplateSpec) Size() (n int) { +func (m *DeviceSelector) Size() (n int) { if m == nil { return 0 } var l int _ = l - l = m.ObjectMeta.Size() + if m.CEL != nil { + l = m.CEL.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + +func (m *DeviceSubRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) n += 1 + l + sovGenerated(uint64(l)) - l = m.Spec.Size() + l = len(m.DeviceClassName) + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Selectors) > 0 { + for _, e := range m.Selectors { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + l = len(m.AllocationMode) n += 1 + l + sovGenerated(uint64(l)) + n += 1 + sovGenerated(uint64(m.Count)) + if len(m.Tolerations) > 0 { + for _, e := range m.Tolerations { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } return n } -func (m *ResourcePool) Size() (n int) { +func (m *DeviceTaint) Size() (n int) { if m == nil { return 0 } var l int _ = l - l = len(m.Name) + l = len(m.Key) n += 1 + l + sovGenerated(uint64(l)) - n += 1 + sovGenerated(uint64(m.Generation)) - n += 1 + sovGenerated(uint64(m.ResourceSliceCount)) + l = len(m.Value) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Effect) + n += 1 + l + sovGenerated(uint64(l)) + if m.TimeAdded != nil { + l = m.TimeAdded.Size() + n += 1 + l + sovGenerated(uint64(l)) + } return n } -func (m *ResourceSlice) Size() (n int) { +func (m *DeviceTaintRule) Size() (n int) { if m == nil { return 0 } @@ -3276,7 +4214,7 @@ func (m *ResourceSlice) Size() (n int) { return n } -func (m *ResourceSliceList) Size() (n int) { +func (m *DeviceTaintRuleList) Size() (n int) { if m == nil { return 0 } @@ -3293,25 +4231,45 @@ func (m *ResourceSliceList) Size() (n int) { return n } -func (m *ResourceSliceSpec) Size() (n int) { +func (m *DeviceTaintRuleSpec) Size() (n int) { if m == nil { return 0 } var l int _ = l - l = len(m.Driver) - n += 1 + l + sovGenerated(uint64(l)) - l = m.Pool.Size() - n += 1 + l + sovGenerated(uint64(l)) - l = len(m.NodeName) + if m.DeviceSelector != nil { + l = m.DeviceSelector.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + l = m.Taint.Size() n += 1 + l + sovGenerated(uint64(l)) - if m.NodeSelector != nil { - l = m.NodeSelector.Size() + return n +} + +func (m *DeviceTaintSelector) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.DeviceClassName != nil { + l = len(*m.DeviceClassName) n += 1 + l + sovGenerated(uint64(l)) } - n += 2 - if len(m.Devices) > 0 { - for _, e := range m.Devices { + if m.Driver != nil { + l = len(*m.Driver) + n += 1 + l + sovGenerated(uint64(l)) + } + if m.Pool != nil { + l = len(*m.Pool) + n += 1 + l + sovGenerated(uint64(l)) + } + if m.Device != nil { + l = len(*m.Device) + n += 1 + l + sovGenerated(uint64(l)) + } + if len(m.Selectors) > 0 { + for _, e := range m.Selectors { l = e.Size() n += 1 + l + sovGenerated(uint64(l)) } @@ -3319,15 +4277,273 @@ func (m *ResourceSliceSpec) Size() (n int) { return n } -func sovGenerated(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozGenerated(x uint64) (n int) { - return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (this *AllocatedDeviceStatus) String() string { - if this == nil { - return "nil" +func (m *DeviceToleration) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Key) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Operator) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Value) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Effect) + n += 1 + l + sovGenerated(uint64(l)) + if m.TolerationSeconds != nil { + n += 1 + sovGenerated(uint64(*m.TolerationSeconds)) + } + return n +} + +func (m *NetworkDeviceData) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.InterfaceName) + n += 1 + l + sovGenerated(uint64(l)) + if len(m.IPs) > 0 { + for _, s := range m.IPs { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } + l = len(m.HardwareAddress) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *OpaqueDeviceConfiguration) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Driver) + n += 1 + l + sovGenerated(uint64(l)) + l = m.Parameters.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *ResourceClaim) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Spec.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Status.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *ResourceClaimConsumerReference) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.APIGroup) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Resource) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.UID) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *ResourceClaimList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ListMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Items) > 0 { + for _, e := range m.Items { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *ResourceClaimSpec) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Devices.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *ResourceClaimStatus) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Allocation != nil { + l = m.Allocation.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if len(m.ReservedFor) > 0 { + for _, e := range m.ReservedFor { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + if len(m.Devices) > 0 { + for _, e := range m.Devices { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *ResourceClaimTemplate) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Spec.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *ResourceClaimTemplateList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ListMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Items) > 0 { + for _, e := range m.Items { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *ResourceClaimTemplateSpec) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Spec.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *ResourcePool) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + n += 1 + sovGenerated(uint64(m.Generation)) + n += 1 + sovGenerated(uint64(m.ResourceSliceCount)) + return n +} + +func (m *ResourceSlice) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = m.Spec.Size() + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *ResourceSliceList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ListMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Items) > 0 { + for _, e := range m.Items { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func (m *ResourceSliceSpec) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Driver) + n += 1 + l + sovGenerated(uint64(l)) + l = m.Pool.Size() + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.NodeName) + n += 1 + l + sovGenerated(uint64(l)) + if m.NodeSelector != nil { + l = m.NodeSelector.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + n += 2 + if len(m.Devices) > 0 { + for _, e := range m.Devices { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + if m.PerDeviceNodeSelection != nil { + n += 2 + } + if len(m.SharedCounters) > 0 { + for _, e := range m.SharedCounters { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + +func sovGenerated(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGenerated(x uint64) (n int) { + return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (this *AllocatedDeviceStatus) String() string { + if this == nil { + return "nil" } repeatedStringForConditions := "[]Condition{" for _, f := range this.Conditions { @@ -3339,7 +4555,7 @@ func (this *AllocatedDeviceStatus) String() string { `Pool:` + fmt.Sprintf("%v", this.Pool) + `,`, `Device:` + fmt.Sprintf("%v", this.Device) + `,`, `Conditions:` + repeatedStringForConditions + `,`, - `Data:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Data), "RawExtension", "runtime.RawExtension", 1), `&`, ``, 1) + `,`, + `Data:` + strings.Replace(fmt.Sprintf("%v", this.Data), "RawExtension", "runtime.RawExtension", 1) + `,`, `NetworkData:` + strings.Replace(this.NetworkData.String(), "NetworkDeviceData", "NetworkDeviceData", 1) + `,`, `}`, }, "") @@ -3360,7 +4576,17 @@ func (this *BasicDevice) String() string { if this == nil { return "nil" } - keysForAttributes := make([]string, 0, len(this.Attributes)) + repeatedStringForConsumesCounters := "[]DeviceCounterConsumption{" + for _, f := range this.ConsumesCounters { + repeatedStringForConsumesCounters += strings.Replace(strings.Replace(f.String(), "DeviceCounterConsumption", "DeviceCounterConsumption", 1), `&`, ``, 1) + "," + } + repeatedStringForConsumesCounters += "}" + repeatedStringForTaints := "[]DeviceTaint{" + for _, f := range this.Taints { + repeatedStringForTaints += strings.Replace(strings.Replace(f.String(), "DeviceTaint", "DeviceTaint", 1), `&`, ``, 1) + "," + } + repeatedStringForTaints += "}" + keysForAttributes := make([]string, 0, len(this.Attributes)) for k := range this.Attributes { keysForAttributes = append(keysForAttributes, string(k)) } @@ -3383,6 +4609,11 @@ func (this *BasicDevice) String() string { s := strings.Join([]string{`&BasicDevice{`, `Attributes:` + mapStringForAttributes + `,`, `Capacity:` + mapStringForCapacity + `,`, + `ConsumesCounters:` + repeatedStringForConsumesCounters + `,`, + `NodeName:` + valueToStringGenerated(this.NodeName) + `,`, + `NodeSelector:` + strings.Replace(fmt.Sprintf("%v", this.NodeSelector), "NodeSelector", "v11.NodeSelector", 1) + `,`, + `AllNodes:` + valueToStringGenerated(this.AllNodes) + `,`, + `Taints:` + repeatedStringForTaints + `,`, `}`, }, "") return s @@ -3397,6 +4628,37 @@ func (this *CELDeviceSelector) String() string { }, "") return s } +func (this *Counter) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&Counter{`, + `Value:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Value), "Quantity", "resource.Quantity", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *CounterSet) String() string { + if this == nil { + return "nil" + } + keysForCounters := make([]string, 0, len(this.Counters)) + for k := range this.Counters { + keysForCounters = append(keysForCounters, k) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForCounters) + mapStringForCounters := "map[string]Counter{" + for _, k := range keysForCounters { + mapStringForCounters += fmt.Sprintf("%v: %v,", k, this.Counters[k]) + } + mapStringForCounters += "}" + s := strings.Join([]string{`&CounterSet{`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `Counters:` + mapStringForCounters + `,`, + `}`, + }, "") + return s +} func (this *Device) String() string { if this == nil { return "nil" @@ -3571,6 +4833,27 @@ func (this *DeviceConstraint) String() string { }, "") return s } +func (this *DeviceCounterConsumption) String() string { + if this == nil { + return "nil" + } + keysForCounters := make([]string, 0, len(this.Counters)) + for k := range this.Counters { + keysForCounters = append(keysForCounters, k) + } + github_com_gogo_protobuf_sortkeys.Strings(keysForCounters) + mapStringForCounters := "map[string]Counter{" + for _, k := range keysForCounters { + mapStringForCounters += fmt.Sprintf("%v: %v,", k, this.Counters[k]) + } + mapStringForCounters += "}" + s := strings.Join([]string{`&DeviceCounterConsumption{`, + `CounterSet:` + fmt.Sprintf("%v", this.CounterSet) + `,`, + `Counters:` + mapStringForCounters + `,`, + `}`, + }, "") + return s +} func (this *DeviceRequest) String() string { if this == nil { return "nil" @@ -3580,6 +4863,16 @@ func (this *DeviceRequest) String() string { repeatedStringForSelectors += strings.Replace(strings.Replace(f.String(), "DeviceSelector", "DeviceSelector", 1), `&`, ``, 1) + "," } repeatedStringForSelectors += "}" + repeatedStringForFirstAvailable := "[]DeviceSubRequest{" + for _, f := range this.FirstAvailable { + repeatedStringForFirstAvailable += strings.Replace(strings.Replace(f.String(), "DeviceSubRequest", "DeviceSubRequest", 1), `&`, ``, 1) + "," + } + repeatedStringForFirstAvailable += "}" + repeatedStringForTolerations := "[]DeviceToleration{" + for _, f := range this.Tolerations { + repeatedStringForTolerations += strings.Replace(strings.Replace(f.String(), "DeviceToleration", "DeviceToleration", 1), `&`, ``, 1) + "," + } + repeatedStringForTolerations += "}" s := strings.Join([]string{`&DeviceRequest{`, `Name:` + fmt.Sprintf("%v", this.Name) + `,`, `DeviceClassName:` + fmt.Sprintf("%v", this.DeviceClassName) + `,`, @@ -3587,6 +4880,8 @@ func (this *DeviceRequest) String() string { `AllocationMode:` + fmt.Sprintf("%v", this.AllocationMode) + `,`, `Count:` + fmt.Sprintf("%v", this.Count) + `,`, `AdminAccess:` + valueToStringGenerated(this.AdminAccess) + `,`, + `FirstAvailable:` + repeatedStringForFirstAvailable + `,`, + `Tolerations:` + repeatedStringForTolerations + `,`, `}`, }, "") return s @@ -3595,12 +4890,18 @@ func (this *DeviceRequestAllocationResult) String() string { if this == nil { return "nil" } + repeatedStringForTolerations := "[]DeviceToleration{" + for _, f := range this.Tolerations { + repeatedStringForTolerations += strings.Replace(strings.Replace(f.String(), "DeviceToleration", "DeviceToleration", 1), `&`, ``, 1) + "," + } + repeatedStringForTolerations += "}" s := strings.Join([]string{`&DeviceRequestAllocationResult{`, `Request:` + fmt.Sprintf("%v", this.Request) + `,`, `Driver:` + fmt.Sprintf("%v", this.Driver) + `,`, `Pool:` + fmt.Sprintf("%v", this.Pool) + `,`, `Device:` + fmt.Sprintf("%v", this.Device) + `,`, `AdminAccess:` + valueToStringGenerated(this.AdminAccess) + `,`, + `Tolerations:` + repeatedStringForTolerations + `,`, `}`, }, "") return s @@ -3615,6 +4916,115 @@ func (this *DeviceSelector) String() string { }, "") return s } +func (this *DeviceSubRequest) String() string { + if this == nil { + return "nil" + } + repeatedStringForSelectors := "[]DeviceSelector{" + for _, f := range this.Selectors { + repeatedStringForSelectors += strings.Replace(strings.Replace(f.String(), "DeviceSelector", "DeviceSelector", 1), `&`, ``, 1) + "," + } + repeatedStringForSelectors += "}" + repeatedStringForTolerations := "[]DeviceToleration{" + for _, f := range this.Tolerations { + repeatedStringForTolerations += strings.Replace(strings.Replace(f.String(), "DeviceToleration", "DeviceToleration", 1), `&`, ``, 1) + "," + } + repeatedStringForTolerations += "}" + s := strings.Join([]string{`&DeviceSubRequest{`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `DeviceClassName:` + fmt.Sprintf("%v", this.DeviceClassName) + `,`, + `Selectors:` + repeatedStringForSelectors + `,`, + `AllocationMode:` + fmt.Sprintf("%v", this.AllocationMode) + `,`, + `Count:` + fmt.Sprintf("%v", this.Count) + `,`, + `Tolerations:` + repeatedStringForTolerations + `,`, + `}`, + }, "") + return s +} +func (this *DeviceTaint) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&DeviceTaint{`, + `Key:` + fmt.Sprintf("%v", this.Key) + `,`, + `Value:` + fmt.Sprintf("%v", this.Value) + `,`, + `Effect:` + fmt.Sprintf("%v", this.Effect) + `,`, + `TimeAdded:` + strings.Replace(fmt.Sprintf("%v", this.TimeAdded), "Time", "v1.Time", 1) + `,`, + `}`, + }, "") + return s +} +func (this *DeviceTaintRule) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&DeviceTaintRule{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, + `Spec:` + strings.Replace(strings.Replace(this.Spec.String(), "DeviceTaintRuleSpec", "DeviceTaintRuleSpec", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *DeviceTaintRuleList) String() string { + if this == nil { + return "nil" + } + repeatedStringForItems := "[]DeviceTaintRule{" + for _, f := range this.Items { + repeatedStringForItems += strings.Replace(strings.Replace(f.String(), "DeviceTaintRule", "DeviceTaintRule", 1), `&`, ``, 1) + "," + } + repeatedStringForItems += "}" + s := strings.Join([]string{`&DeviceTaintRuleList{`, + `ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`, + `Items:` + repeatedStringForItems + `,`, + `}`, + }, "") + return s +} +func (this *DeviceTaintRuleSpec) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&DeviceTaintRuleSpec{`, + `DeviceSelector:` + strings.Replace(this.DeviceSelector.String(), "DeviceTaintSelector", "DeviceTaintSelector", 1) + `,`, + `Taint:` + strings.Replace(strings.Replace(this.Taint.String(), "DeviceTaint", "DeviceTaint", 1), `&`, ``, 1) + `,`, + `}`, + }, "") + return s +} +func (this *DeviceTaintSelector) String() string { + if this == nil { + return "nil" + } + repeatedStringForSelectors := "[]DeviceSelector{" + for _, f := range this.Selectors { + repeatedStringForSelectors += strings.Replace(strings.Replace(f.String(), "DeviceSelector", "DeviceSelector", 1), `&`, ``, 1) + "," + } + repeatedStringForSelectors += "}" + s := strings.Join([]string{`&DeviceTaintSelector{`, + `DeviceClassName:` + valueToStringGenerated(this.DeviceClassName) + `,`, + `Driver:` + valueToStringGenerated(this.Driver) + `,`, + `Pool:` + valueToStringGenerated(this.Pool) + `,`, + `Device:` + valueToStringGenerated(this.Device) + `,`, + `Selectors:` + repeatedStringForSelectors + `,`, + `}`, + }, "") + return s +} +func (this *DeviceToleration) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&DeviceToleration{`, + `Key:` + fmt.Sprintf("%v", this.Key) + `,`, + `Operator:` + fmt.Sprintf("%v", this.Operator) + `,`, + `Value:` + fmt.Sprintf("%v", this.Value) + `,`, + `Effect:` + fmt.Sprintf("%v", this.Effect) + `,`, + `TolerationSeconds:` + valueToStringGenerated(this.TolerationSeconds) + `,`, + `}`, + }, "") + return s +} func (this *NetworkDeviceData) String() string { if this == nil { return "nil" @@ -3797,6 +5207,11 @@ func (this *ResourceSliceSpec) String() string { repeatedStringForDevices += strings.Replace(strings.Replace(f.String(), "Device", "Device", 1), `&`, ``, 1) + "," } repeatedStringForDevices += "}" + repeatedStringForSharedCounters := "[]CounterSet{" + for _, f := range this.SharedCounters { + repeatedStringForSharedCounters += strings.Replace(strings.Replace(f.String(), "CounterSet", "CounterSet", 1), `&`, ``, 1) + "," + } + repeatedStringForSharedCounters += "}" s := strings.Join([]string{`&ResourceSliceSpec{`, `Driver:` + fmt.Sprintf("%v", this.Driver) + `,`, `Pool:` + strings.Replace(strings.Replace(this.Pool.String(), "ResourcePool", "ResourcePool", 1), `&`, ``, 1) + `,`, @@ -3804,6 +5219,8 @@ func (this *ResourceSliceSpec) String() string { `NodeSelector:` + strings.Replace(fmt.Sprintf("%v", this.NodeSelector), "NodeSelector", "v11.NodeSelector", 1) + `,`, `AllNodes:` + fmt.Sprintf("%v", this.AllNodes) + `,`, `Devices:` + repeatedStringForDevices + `,`, + `PerDeviceNodeSelection:` + valueToStringGenerated(this.PerDeviceNodeSelection) + `,`, + `SharedCounters:` + repeatedStringForSharedCounters + `,`, `}`, }, "") return s @@ -3813,10 +5230,1915 @@ func valueToStringGenerated(v interface{}) string { if rv.IsNil() { return "nil" } - pv := reflect.Indirect(rv).Interface() - return fmt.Sprintf("*%v", pv) + pv := reflect.Indirect(rv).Interface() + return fmt.Sprintf("*%v", pv) +} +func (m *AllocatedDeviceStatus) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AllocatedDeviceStatus: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AllocatedDeviceStatus: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Driver", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Driver = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pool", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Pool = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Device", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Device = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Conditions", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Conditions = append(m.Conditions, v1.Condition{}) + if err := m.Conditions[len(m.Conditions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Data == nil { + m.Data = &runtime.RawExtension{} + } + if err := m.Data.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NetworkData", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.NetworkData == nil { + m.NetworkData = &NetworkDeviceData{} + } + if err := m.NetworkData.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *AllocationResult) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AllocationResult: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AllocationResult: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Devices", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Devices.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NodeSelector", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.NodeSelector == nil { + m.NodeSelector = &v11.NodeSelector{} + } + if err := m.NodeSelector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *BasicDevice) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: BasicDevice: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: BasicDevice: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Attributes", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Attributes == nil { + m.Attributes = make(map[QualifiedName]DeviceAttribute) + } + var mapkey QualifiedName + mapvalue := &DeviceAttribute{} + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthGenerated + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLengthGenerated + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = QualifiedName(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var mapmsglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + mapmsglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if mapmsglen < 0 { + return ErrInvalidLengthGenerated + } + postmsgIndex := iNdEx + mapmsglen + if postmsgIndex < 0 { + return ErrInvalidLengthGenerated + } + if postmsgIndex > l { + return io.ErrUnexpectedEOF + } + mapvalue = &DeviceAttribute{} + if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil { + return err + } + iNdEx = postmsgIndex + } else { + iNdEx = entryPreIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.Attributes[QualifiedName(mapkey)] = *mapvalue + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Capacity", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Capacity == nil { + m.Capacity = make(map[QualifiedName]resource.Quantity) + } + var mapkey QualifiedName + mapvalue := &resource.Quantity{} + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthGenerated + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLengthGenerated + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = QualifiedName(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var mapmsglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + mapmsglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if mapmsglen < 0 { + return ErrInvalidLengthGenerated + } + postmsgIndex := iNdEx + mapmsglen + if postmsgIndex < 0 { + return ErrInvalidLengthGenerated + } + if postmsgIndex > l { + return io.ErrUnexpectedEOF + } + mapvalue = &resource.Quantity{} + if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil { + return err + } + iNdEx = postmsgIndex + } else { + iNdEx = entryPreIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.Capacity[QualifiedName(mapkey)] = *mapvalue + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ConsumesCounters", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ConsumesCounters = append(m.ConsumesCounters, DeviceCounterConsumption{}) + if err := m.ConsumesCounters[len(m.ConsumesCounters)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NodeName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.NodeName = &s + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NodeSelector", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.NodeSelector == nil { + m.NodeSelector = &v11.NodeSelector{} + } + if err := m.NodeSelector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field AllNodes", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + b := bool(v != 0) + m.AllNodes = &b + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Taints", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Taints = append(m.Taints, DeviceTaint{}) + if err := m.Taints[len(m.Taints)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *CELDeviceSelector) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: CELDeviceSelector: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CELDeviceSelector: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Expression", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Expression = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Counter) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Counter: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Counter: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Value.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *CounterSet) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: CounterSet: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CounterSet: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Counters", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Counters == nil { + m.Counters = make(map[string]Counter) + } + var mapkey string + mapvalue := &Counter{} + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthGenerated + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLengthGenerated + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var mapmsglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + mapmsglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if mapmsglen < 0 { + return ErrInvalidLengthGenerated + } + postmsgIndex := iNdEx + mapmsglen + if postmsgIndex < 0 { + return ErrInvalidLengthGenerated + } + if postmsgIndex > l { + return io.ErrUnexpectedEOF + } + mapvalue = &Counter{} + if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil { + return err + } + iNdEx = postmsgIndex + } else { + iNdEx = entryPreIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.Counters[mapkey] = *mapvalue + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Device) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Device: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Device: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Basic", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Basic == nil { + m.Basic = &BasicDevice{} + } + if err := m.Basic.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DeviceAllocationConfiguration) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DeviceAllocationConfiguration: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DeviceAllocationConfiguration: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Source", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Source = AllocationConfigSource(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Requests", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Requests = append(m.Requests, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DeviceConfiguration", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.DeviceConfiguration.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DeviceAllocationResult) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DeviceAllocationResult: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DeviceAllocationResult: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Results", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Results = append(m.Results, DeviceRequestAllocationResult{}) + if err := m.Results[len(m.Results)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Config", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Config = append(m.Config, DeviceAllocationConfiguration{}) + if err := m.Config[len(m.Config)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DeviceAttribute) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DeviceAttribute: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DeviceAttribute: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field IntValue", wireType) + } + var v int64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.IntValue = &v + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field BoolValue", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + b := bool(v != 0) + m.BoolValue = &b + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field StringValue", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.StringValue = &s + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field VersionValue", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.VersionValue = &s + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DeviceClaim) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DeviceClaim: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DeviceClaim: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Requests", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Requests = append(m.Requests, DeviceRequest{}) + if err := m.Requests[len(m.Requests)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Constraints", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Constraints = append(m.Constraints, DeviceConstraint{}) + if err := m.Constraints[len(m.Constraints)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Config", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Config = append(m.Config, DeviceClaimConfiguration{}) + if err := m.Config[len(m.Config)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil } -func (m *AllocatedDeviceStatus) Unmarshal(dAtA []byte) error { +func (m *DeviceClaimConfiguration) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3839,15 +7161,15 @@ func (m *AllocatedDeviceStatus) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: AllocatedDeviceStatus: wiretype end group for non-group") + return fmt.Errorf("proto: DeviceClaimConfiguration: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: AllocatedDeviceStatus: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: DeviceClaimConfiguration: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Driver", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Requests", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -3875,13 +7197,13 @@ func (m *AllocatedDeviceStatus) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Driver = string(dAtA[iNdEx:postIndex]) + m.Requests = append(m.Requests, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Pool", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field DeviceConfiguration", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -3891,29 +7213,80 @@ func (m *AllocatedDeviceStatus) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.Pool = string(dAtA[iNdEx:postIndex]) + if err := m.DeviceConfiguration.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 3: + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DeviceClass) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DeviceClass: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DeviceClass: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Device", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -3923,27 +7296,28 @@ func (m *AllocatedDeviceStatus) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.Device = string(dAtA[iNdEx:postIndex]) + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 4: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Conditions", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -3970,14 +7344,63 @@ func (m *AllocatedDeviceStatus) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Conditions = append(m.Conditions, v1.Condition{}) - if err := m.Conditions[len(m.Conditions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 5: + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DeviceClassConfiguration) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DeviceClassConfiguration: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DeviceClassConfiguration: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field DeviceConfiguration", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -4004,13 +7427,63 @@ func (m *AllocatedDeviceStatus) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Data.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.DeviceConfiguration.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 6: + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DeviceClassList) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DeviceClassList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DeviceClassList: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field NetworkData", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -4037,10 +7510,41 @@ func (m *AllocatedDeviceStatus) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.NetworkData == nil { - m.NetworkData = &NetworkDeviceData{} + if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err } - if err := m.NetworkData.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Items = append(m.Items, DeviceClass{}) + if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -4065,7 +7569,7 @@ func (m *AllocatedDeviceStatus) Unmarshal(dAtA []byte) error { } return nil } -func (m *AllocationResult) Unmarshal(dAtA []byte) error { +func (m *DeviceClassSpec) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4088,15 +7592,15 @@ func (m *AllocationResult) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: AllocationResult: wiretype end group for non-group") + return fmt.Errorf("proto: DeviceClassSpec: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: AllocationResult: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: DeviceClassSpec: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Devices", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Selectors", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -4123,13 +7627,14 @@ func (m *AllocationResult) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Devices.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Selectors = append(m.Selectors, DeviceSelector{}) + if err := m.Selectors[len(m.Selectors)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 3: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field NodeSelector", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Config", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -4156,10 +7661,8 @@ func (m *AllocationResult) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.NodeSelector == nil { - m.NodeSelector = &v11.NodeSelector{} - } - if err := m.NodeSelector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Config = append(m.Config, DeviceClassConfiguration{}) + if err := m.Config[len(m.Config)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -4184,7 +7687,7 @@ func (m *AllocationResult) Unmarshal(dAtA []byte) error { } return nil } -func (m *BasicDevice) Unmarshal(dAtA []byte) error { +func (m *DeviceConfiguration) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4207,144 +7710,15 @@ func (m *BasicDevice) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: BasicDevice: wiretype end group for non-group") + return fmt.Errorf("proto: DeviceConfiguration: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: BasicDevice: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: DeviceConfiguration: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Attributes", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Attributes == nil { - m.Attributes = make(map[QualifiedName]DeviceAttribute) - } - var mapkey QualifiedName - mapvalue := &DeviceAttribute{} - for iNdEx < postIndex { - entryPreIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - if fieldNum == 1 { - var stringLenmapkey uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapkey |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapkey := int(stringLenmapkey) - if intStringLenmapkey < 0 { - return ErrInvalidLengthGenerated - } - postStringIndexmapkey := iNdEx + intStringLenmapkey - if postStringIndexmapkey < 0 { - return ErrInvalidLengthGenerated - } - if postStringIndexmapkey > l { - return io.ErrUnexpectedEOF - } - mapkey = QualifiedName(dAtA[iNdEx:postStringIndexmapkey]) - iNdEx = postStringIndexmapkey - } else if fieldNum == 2 { - var mapmsglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - mapmsglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if mapmsglen < 0 { - return ErrInvalidLengthGenerated - } - postmsgIndex := iNdEx + mapmsglen - if postmsgIndex < 0 { - return ErrInvalidLengthGenerated - } - if postmsgIndex > l { - return io.ErrUnexpectedEOF - } - mapvalue = &DeviceAttribute{} - if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil { - return err - } - iNdEx = postmsgIndex - } else { - iNdEx = entryPreIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > postIndex { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - m.Attributes[QualifiedName(mapkey)] = *mapvalue - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Capacity", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Opaque", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -4371,105 +7745,12 @@ func (m *BasicDevice) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Capacity == nil { - m.Capacity = make(map[QualifiedName]resource.Quantity) + if m.Opaque == nil { + m.Opaque = &OpaqueDeviceConfiguration{} } - var mapkey QualifiedName - mapvalue := &resource.Quantity{} - for iNdEx < postIndex { - entryPreIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - if fieldNum == 1 { - var stringLenmapkey uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapkey |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapkey := int(stringLenmapkey) - if intStringLenmapkey < 0 { - return ErrInvalidLengthGenerated - } - postStringIndexmapkey := iNdEx + intStringLenmapkey - if postStringIndexmapkey < 0 { - return ErrInvalidLengthGenerated - } - if postStringIndexmapkey > l { - return io.ErrUnexpectedEOF - } - mapkey = QualifiedName(dAtA[iNdEx:postStringIndexmapkey]) - iNdEx = postStringIndexmapkey - } else if fieldNum == 2 { - var mapmsglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - mapmsglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if mapmsglen < 0 { - return ErrInvalidLengthGenerated - } - postmsgIndex := iNdEx + mapmsglen - if postmsgIndex < 0 { - return ErrInvalidLengthGenerated - } - if postmsgIndex > l { - return io.ErrUnexpectedEOF - } - mapvalue = &resource.Quantity{} - if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil { - return err - } - iNdEx = postmsgIndex - } else { - iNdEx = entryPreIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > postIndex { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } + if err := m.Opaque.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err } - m.Capacity[QualifiedName(mapkey)] = *mapvalue iNdEx = postIndex default: iNdEx = preIndex @@ -4492,7 +7773,7 @@ func (m *BasicDevice) Unmarshal(dAtA []byte) error { } return nil } -func (m *CELDeviceSelector) Unmarshal(dAtA []byte) error { +func (m *DeviceConstraint) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4515,15 +7796,15 @@ func (m *CELDeviceSelector) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: CELDeviceSelector: wiretype end group for non-group") + return fmt.Errorf("proto: DeviceConstraint: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: CELDeviceSelector: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: DeviceConstraint: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Expression", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Requests", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -4551,7 +7832,40 @@ func (m *CELDeviceSelector) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Expression = string(dAtA[iNdEx:postIndex]) + m.Requests = append(m.Requests, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MatchAttribute", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := FullyQualifiedName(dAtA[iNdEx:postIndex]) + m.MatchAttribute = &s iNdEx = postIndex default: iNdEx = preIndex @@ -4574,7 +7888,7 @@ func (m *CELDeviceSelector) Unmarshal(dAtA []byte) error { } return nil } -func (m *Device) Unmarshal(dAtA []byte) error { +func (m *DeviceCounterConsumption) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4597,15 +7911,15 @@ func (m *Device) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Device: wiretype end group for non-group") + return fmt.Errorf("proto: DeviceCounterConsumption: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Device: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: DeviceCounterConsumption: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field CounterSet", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -4633,11 +7947,11 @@ func (m *Device) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Name = string(dAtA[iNdEx:postIndex]) + m.CounterSet = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Basic", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Counters", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -4664,12 +7978,105 @@ func (m *Device) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Basic == nil { - m.Basic = &BasicDevice{} + if m.Counters == nil { + m.Counters = make(map[string]Counter) } - if err := m.Basic.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + var mapkey string + mapvalue := &Counter{} + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLengthGenerated + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLengthGenerated + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var mapmsglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + mapmsglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if mapmsglen < 0 { + return ErrInvalidLengthGenerated + } + postmsgIndex := iNdEx + mapmsglen + if postmsgIndex < 0 { + return ErrInvalidLengthGenerated + } + if postmsgIndex > l { + return io.ErrUnexpectedEOF + } + mapvalue = &Counter{} + if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil { + return err + } + iNdEx = postmsgIndex + } else { + iNdEx = entryPreIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } } + m.Counters[mapkey] = *mapvalue iNdEx = postIndex default: iNdEx = preIndex @@ -4692,7 +8099,7 @@ func (m *Device) Unmarshal(dAtA []byte) error { } return nil } -func (m *DeviceAllocationConfiguration) Unmarshal(dAtA []byte) error { +func (m *DeviceRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4715,15 +8122,15 @@ func (m *DeviceAllocationConfiguration) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: DeviceAllocationConfiguration: wiretype end group for non-group") + return fmt.Errorf("proto: DeviceRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: DeviceAllocationConfiguration: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: DeviceRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Source", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -4751,11 +8158,11 @@ func (m *DeviceAllocationConfiguration) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Source = AllocationConfigSource(dAtA[iNdEx:postIndex]) + m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Requests", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field DeviceClassName", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -4783,11 +8190,11 @@ func (m *DeviceAllocationConfiguration) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Requests = append(m.Requests, string(dAtA[iNdEx:postIndex])) + m.DeviceClassName = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DeviceConfiguration", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Selectors", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -4814,63 +8221,86 @@ func (m *DeviceAllocationConfiguration) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.DeviceConfiguration.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Selectors = append(m.Selectors, DeviceSelector{}) + if err := m.Selectors[len(m.Selectors)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AllocationMode", wireType) } - if (skippy < 0) || (iNdEx+skippy) < 0 { + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - if (iNdEx + skippy) > l { + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { return io.ErrUnexpectedEOF } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *DeviceAllocationResult) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated + m.AllocationMode = DeviceAllocationMode(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Count", wireType) } - if iNdEx >= l { - return io.ErrUnexpectedEOF + m.Count = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Count |= int64(b&0x7F) << shift + if b < 0x80 { + break + } } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field AdminAccess", wireType) } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: DeviceAllocationResult: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: DeviceAllocationResult: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + b := bool(v != 0) + m.AdminAccess = &b + case 7: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Results", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field FirstAvailable", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -4897,14 +8327,14 @@ func (m *DeviceAllocationResult) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Results = append(m.Results, DeviceRequestAllocationResult{}) - if err := m.Results[len(m.Results)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.FirstAvailable = append(m.FirstAvailable, DeviceSubRequest{}) + if err := m.FirstAvailable[len(m.FirstAvailable)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 2: + case 8: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Config", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Tolerations", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -4931,8 +8361,8 @@ func (m *DeviceAllocationResult) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Config = append(m.Config, DeviceAllocationConfiguration{}) - if err := m.Config[len(m.Config)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Tolerations = append(m.Tolerations, DeviceToleration{}) + if err := m.Tolerations[len(m.Tolerations)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -4957,7 +8387,7 @@ func (m *DeviceAllocationResult) Unmarshal(dAtA []byte) error { } return nil } -func (m *DeviceAttribute) Unmarshal(dAtA []byte) error { +func (m *DeviceRequestAllocationResult) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4980,17 +8410,17 @@ func (m *DeviceAttribute) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: DeviceAttribute: wiretype end group for non-group") + return fmt.Errorf("proto: DeviceRequestAllocationResult: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: DeviceAttribute: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: DeviceRequestAllocationResult: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field IntValue", wireType) + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Request", wireType) } - var v int64 + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -5000,17 +8430,29 @@ func (m *DeviceAttribute) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - v |= int64(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - m.IntValue = &v - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field BoolValue", wireType) + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated } - var v int + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Request = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Driver", wireType) + } + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -5020,16 +8462,27 @@ func (m *DeviceAttribute) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - v |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - b := bool(v != 0) - m.BoolValue = &b - case 4: + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Driver = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field StringValue", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Pool", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -5057,12 +8510,11 @@ func (m *DeviceAttribute) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - s := string(dAtA[iNdEx:postIndex]) - m.StringValue = &s + m.Pool = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 5: + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field VersionValue", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Device", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -5090,8 +8542,62 @@ func (m *DeviceAttribute) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - s := string(dAtA[iNdEx:postIndex]) - m.VersionValue = &s + m.Device = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field AdminAccess", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + b := bool(v != 0) + m.AdminAccess = &b + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Tolerations", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Tolerations = append(m.Tolerations, DeviceToleration{}) + if err := m.Tolerations[len(m.Tolerations)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -5114,7 +8620,7 @@ func (m *DeviceAttribute) Unmarshal(dAtA []byte) error { } return nil } -func (m *DeviceClaim) Unmarshal(dAtA []byte) error { +func (m *DeviceSelector) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -5137,49 +8643,15 @@ func (m *DeviceClaim) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: DeviceClaim: wiretype end group for non-group") + return fmt.Errorf("proto: DeviceSelector: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: DeviceClaim: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: DeviceSelector: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Requests", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Requests = append(m.Requests, DeviceRequest{}) - if err := m.Requests[len(m.Requests)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Constraints", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field CEL", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -5206,42 +8678,10 @@ func (m *DeviceClaim) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Constraints = append(m.Constraints, DeviceConstraint{}) - if err := m.Constraints[len(m.Constraints)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Config", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF + if m.CEL == nil { + m.CEL = &CELDeviceSelector{} } - m.Config = append(m.Config, DeviceClaimConfiguration{}) - if err := m.Config[len(m.Config)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.CEL.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -5266,7 +8706,7 @@ func (m *DeviceClaim) Unmarshal(dAtA []byte) error { } return nil } -func (m *DeviceClaimConfiguration) Unmarshal(dAtA []byte) error { +func (m *DeviceSubRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -5289,15 +8729,47 @@ func (m *DeviceClaimConfiguration) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: DeviceClaimConfiguration: wiretype end group for non-group") + return fmt.Errorf("proto: DeviceSubRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: DeviceClaimConfiguration: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: DeviceSubRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Requests", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DeviceClassName", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -5325,11 +8797,11 @@ func (m *DeviceClaimConfiguration) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Requests = append(m.Requests, string(dAtA[iNdEx:postIndex])) + m.DeviceClassName = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 2: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DeviceConfiguration", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Selectors", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -5356,65 +8828,16 @@ func (m *DeviceClaimConfiguration) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.DeviceConfiguration.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Selectors = append(m.Selectors, DeviceSelector{}) + if err := m.Selectors[len(m.Selectors)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *DeviceClass) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: DeviceClass: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: DeviceClass: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field AllocationMode", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -5424,28 +8847,46 @@ func (m *DeviceClass) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.AllocationMode = DeviceAllocationMode(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 2: + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Count", wireType) + } + m.Count = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Count |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 7: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Tolerations", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -5472,7 +8913,8 @@ func (m *DeviceClass) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Tolerations = append(m.Tolerations, DeviceToleration{}) + if err := m.Tolerations[len(m.Tolerations)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -5497,7 +8939,7 @@ func (m *DeviceClass) Unmarshal(dAtA []byte) error { } return nil } -func (m *DeviceClassConfiguration) Unmarshal(dAtA []byte) error { +func (m *DeviceTaint) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -5520,17 +8962,17 @@ func (m *DeviceClassConfiguration) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: DeviceClassConfiguration: wiretype end group for non-group") + return fmt.Errorf("proto: DeviceTaint: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: DeviceClassConfiguration: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: DeviceTaint: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DeviceConfiguration", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -5540,80 +8982,61 @@ func (m *DeviceClassConfiguration) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.DeviceConfiguration.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Key = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *DeviceClassList) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated } - if iNdEx >= l { + if postIndex > l { return io.ErrUnexpectedEOF } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: DeviceClassList: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: DeviceClassList: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + m.Value = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Effect", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -5623,28 +9046,27 @@ func (m *DeviceClassList) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Effect = DeviceTaintEffect(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 2: + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field TimeAdded", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -5671,8 +9093,10 @@ func (m *DeviceClassList) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Items = append(m.Items, DeviceClass{}) - if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if m.TimeAdded == nil { + m.TimeAdded = &v1.Time{} + } + if err := m.TimeAdded.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -5697,7 +9121,7 @@ func (m *DeviceClassList) Unmarshal(dAtA []byte) error { } return nil } -func (m *DeviceClassSpec) Unmarshal(dAtA []byte) error { +func (m *DeviceTaintRule) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -5720,15 +9144,15 @@ func (m *DeviceClassSpec) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: DeviceClassSpec: wiretype end group for non-group") + return fmt.Errorf("proto: DeviceTaintRule: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: DeviceClassSpec: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: DeviceTaintRule: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Selectors", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -5755,14 +9179,13 @@ func (m *DeviceClassSpec) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Selectors = append(m.Selectors, DeviceSelector{}) - if err := m.Selectors[len(m.Selectors)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Config", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Spec", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -5789,8 +9212,7 @@ func (m *DeviceClassSpec) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Config = append(m.Config, DeviceClassConfiguration{}) - if err := m.Config[len(m.Config)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Spec.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -5815,7 +9237,7 @@ func (m *DeviceClassSpec) Unmarshal(dAtA []byte) error { } return nil } -func (m *DeviceConfiguration) Unmarshal(dAtA []byte) error { +func (m *DeviceTaintRuleList) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -5838,15 +9260,15 @@ func (m *DeviceConfiguration) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: DeviceConfiguration: wiretype end group for non-group") + return fmt.Errorf("proto: DeviceTaintRuleList: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: DeviceConfiguration: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: DeviceTaintRuleList: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Opaque", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -5873,10 +9295,41 @@ func (m *DeviceConfiguration) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Opaque == nil { - m.Opaque = &OpaqueDeviceConfiguration{} + if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF } - if err := m.Opaque.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Items = append(m.Items, DeviceTaintRule{}) + if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -5901,7 +9354,7 @@ func (m *DeviceConfiguration) Unmarshal(dAtA []byte) error { } return nil } -func (m *DeviceConstraint) Unmarshal(dAtA []byte) error { +func (m *DeviceTaintRuleSpec) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -5924,17 +9377,17 @@ func (m *DeviceConstraint) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: DeviceConstraint: wiretype end group for non-group") + return fmt.Errorf("proto: DeviceTaintRuleSpec: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: DeviceConstraint: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: DeviceTaintRuleSpec: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Requests", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field DeviceSelector", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -5944,29 +9397,33 @@ func (m *DeviceConstraint) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.Requests = append(m.Requests, string(dAtA[iNdEx:postIndex])) + if m.DeviceSelector == nil { + m.DeviceSelector = &DeviceTaintSelector{} + } + if err := m.DeviceSelector.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field MatchAttribute", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Taint", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -5976,24 +9433,24 @@ func (m *DeviceConstraint) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - s := FullyQualifiedName(dAtA[iNdEx:postIndex]) - m.MatchAttribute = &s + if err := m.Taint.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -6016,7 +9473,7 @@ func (m *DeviceConstraint) Unmarshal(dAtA []byte) error { } return nil } -func (m *DeviceRequest) Unmarshal(dAtA []byte) error { +func (m *DeviceTaintSelector) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -6039,15 +9496,15 @@ func (m *DeviceRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: DeviceRequest: wiretype end group for non-group") + return fmt.Errorf("proto: DeviceTaintSelector: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: DeviceRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: DeviceTaintSelector: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field DeviceClassName", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -6075,11 +9532,12 @@ func (m *DeviceRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Name = string(dAtA[iNdEx:postIndex]) + s := string(dAtA[iNdEx:postIndex]) + m.DeviceClassName = &s iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DeviceClassName", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Driver", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -6107,13 +9565,14 @@ func (m *DeviceRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.DeviceClassName = string(dAtA[iNdEx:postIndex]) + s := string(dAtA[iNdEx:postIndex]) + m.Driver = &s iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Selectors", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Pool", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -6123,29 +9582,28 @@ func (m *DeviceRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - m.Selectors = append(m.Selectors, DeviceSelector{}) - if err := m.Selectors[len(m.Selectors)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + s := string(dAtA[iNdEx:postIndex]) + m.Pool = &s iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AllocationMode", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Device", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -6173,13 +9631,14 @@ func (m *DeviceRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.AllocationMode = DeviceAllocationMode(dAtA[iNdEx:postIndex]) + s := string(dAtA[iNdEx:postIndex]) + m.Device = &s iNdEx = postIndex case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Count", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Selectors", wireType) } - m.Count = 0 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -6189,32 +9648,26 @@ func (m *DeviceRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Count |= int64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - case 6: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field AdminAccess", wireType) + if msglen < 0 { + return ErrInvalidLengthGenerated } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated } - b := bool(v != 0) - m.AdminAccess = &b + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Selectors = append(m.Selectors, DeviceSelector{}) + if err := m.Selectors[len(m.Selectors)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -6236,7 +9689,7 @@ func (m *DeviceRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *DeviceRequestAllocationResult) Unmarshal(dAtA []byte) error { +func (m *DeviceToleration) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -6259,15 +9712,15 @@ func (m *DeviceRequestAllocationResult) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: DeviceRequestAllocationResult: wiretype end group for non-group") + return fmt.Errorf("proto: DeviceToleration: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: DeviceRequestAllocationResult: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: DeviceToleration: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Request", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -6295,11 +9748,11 @@ func (m *DeviceRequestAllocationResult) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Request = string(dAtA[iNdEx:postIndex]) + m.Key = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Driver", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Operator", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -6327,11 +9780,11 @@ func (m *DeviceRequestAllocationResult) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Driver = string(dAtA[iNdEx:postIndex]) + m.Operator = DeviceTolerationOperator(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Pool", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -6359,11 +9812,11 @@ func (m *DeviceRequestAllocationResult) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Pool = string(dAtA[iNdEx:postIndex]) + m.Value = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Device", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Effect", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -6391,84 +9844,13 @@ func (m *DeviceRequestAllocationResult) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Device = string(dAtA[iNdEx:postIndex]) + m.Effect = DeviceTaintEffect(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 5: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field AdminAccess", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - b := bool(v != 0) - m.AdminAccess = &b - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenerated - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *DeviceSelector) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenerated - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: DeviceSelector: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: DeviceSelector: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CEL", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field TolerationSeconds", wireType) } - var msglen int + var v int64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -6478,28 +9860,12 @@ func (m *DeviceSelector) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + v |= int64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { - return ErrInvalidLengthGenerated - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenerated - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.CEL == nil { - m.CEL = &CELDeviceSelector{} - } - if err := m.CEL.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex + m.TolerationSeconds = &v default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -8381,6 +11747,61 @@ func (m *ResourceSliceSpec) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PerDeviceNodeSelection", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + b := bool(v != 0) + m.PerDeviceNodeSelection = &b + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SharedCounters", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SharedCounters = append(m.SharedCounters, CounterSet{}) + if err := m.SharedCounters[len(m.SharedCounters)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/go-controller/vendor/k8s.io/api/resource/v1alpha3/generated.proto b/go-controller/vendor/k8s.io/api/resource/v1alpha3/generated.proto index e802a01439..103cafc6ad 100644 --- a/go-controller/vendor/k8s.io/api/resource/v1alpha3/generated.proto +++ b/go-controller/vendor/k8s.io/api/resource/v1alpha3/generated.proto @@ -62,6 +62,8 @@ message AllocatedDeviceStatus { // If the device has been configured according to the class and claim // config references, the `Ready` condition should be True. // + // Must not contain more than 8 entries. + // // +optional // +listType=map // +listMapKey=type @@ -111,6 +113,64 @@ message BasicDevice { // // +optional map capacity = 2; + + // ConsumesCounters defines a list of references to sharedCounters + // and the set of counters that the device will + // consume from those counter sets. + // + // There can only be a single entry per counterSet. + // + // The total number of device counter consumption entries + // must be <= 32. In addition, the total number in the + // entire ResourceSlice must be <= 1024 (for example, + // 64 devices with 16 counters each). + // + // +optional + // +listType=atomic + // +featureGate=DRAPartitionableDevices + repeated DeviceCounterConsumption consumesCounters = 3; + + // NodeName identifies the node where the device is available. + // + // Must only be set if Spec.PerDeviceNodeSelection is set to true. + // At most one of NodeName, NodeSelector and AllNodes can be set. + // + // +optional + // +oneOf=DeviceNodeSelection + // +featureGate=DRAPartitionableDevices + optional string nodeName = 4; + + // NodeSelector defines the nodes where the device is available. + // + // Must only be set if Spec.PerDeviceNodeSelection is set to true. + // At most one of NodeName, NodeSelector and AllNodes can be set. + // + // +optional + // +oneOf=DeviceNodeSelection + // +featureGate=DRAPartitionableDevices + optional .k8s.io.api.core.v1.NodeSelector nodeSelector = 5; + + // AllNodes indicates that all nodes have access to the device. + // + // Must only be set if Spec.PerDeviceNodeSelection is set to true. + // At most one of NodeName, NodeSelector and AllNodes can be set. + // + // +optional + // +oneOf=DeviceNodeSelection + // +featureGate=DRAPartitionableDevices + optional bool allNodes = 6; + + // If specified, these are the driver-defined taints. + // + // The maximum number of taints is 4. + // + // This is an alpha field and requires enabling the DRADeviceTaints + // feature gate. + // + // +optional + // +listType=atomic + // +featureGate=DRADeviceTaints + repeated DeviceTaint taints = 7; } // CELDeviceSelector contains a CEL expression for selecting a device. @@ -170,6 +230,42 @@ message CELDeviceSelector { optional string expression = 1; } +// Counter describes a quantity associated with a device. +message Counter { + // Value defines how much of a certain device counter is available. + // + // +required + optional .k8s.io.apimachinery.pkg.api.resource.Quantity value = 1; +} + +// CounterSet defines a named set of counters +// that are available to be used by devices defined in the +// ResourceSlice. +// +// The counters are not allocatable by themselves, but +// can be referenced by devices. When a device is allocated, +// the portion of counters it uses will no longer be available for use +// by other devices. +message CounterSet { + // CounterSet is the name of the set from which the + // counters defined will be consumed. + // + // +required + optional string name = 1; + + // Counters defines the counters that will be consumed by the device. + // The name of each counter must be unique in that set and must be a DNS label. + // + // To ensure this uniqueness, capacities defined by the vendor + // must be listed without the driver name as domain prefix in + // their name. All others must be listed with their domain prefix. + // + // The maximum number of counters is 32. + // + // +required + map counters = 2; +} + // Device represents one individual hardware instance that can be selected based // on its attributes. Besides the name, exactly one field must be set. message Device { @@ -198,6 +294,10 @@ message DeviceAllocationConfiguration { // Requests lists the names of requests where the configuration applies. // If empty, its applies to all requests. // + // References to subrequests must include the name of the main request + // and may include the subrequest using the format

[/]. If just + // the main request is given, the configuration applies to all subrequests. + // // +optional // +listType=atomic repeated string requests = 2; @@ -284,6 +384,10 @@ message DeviceClaimConfiguration { // Requests lists the names of requests where the configuration applies. // If empty, it applies to all requests. // + // References to subrequests must include the name of the main request + // and may include the subrequest using the format
[/]. If just + // the main request is given, the configuration applies to all subrequests. + // // +optional // +listType=atomic repeated string requests = 1; @@ -368,6 +472,10 @@ message DeviceConstraint { // constraint. If this is not specified, this constraint applies to all // requests in this claim. // + // References to subrequests must include the name of the main request + // and may include the subrequest using the format
[/]. If just + // the main request is given, the constraint applies to all subrequests. + // // +optional // +listType=atomic repeated string requests = 1; @@ -390,14 +498,30 @@ message DeviceConstraint { optional string matchAttribute = 2; } +// DeviceCounterConsumption defines a set of counters that +// a device will consume from a CounterSet. +message DeviceCounterConsumption { + // CounterSet defines the set from which the + // counters defined will be consumed. + // + // +required + optional string counterSet = 1; + + // Counters defines the Counter that will be consumed by + // the device. + // + // The maximum number counters in a device is 32. + // In addition, the maximum number of all counters + // in all devices is 1024 (for example, 64 devices with + // 16 counters each). + // + // +required + map counters = 2; +} + // DeviceRequest is a request for devices required for a claim. // This is typically a request for a single resource like a device, but can // also ask for several identical devices. -// -// A DeviceClassName is currently required. Clients must check that it is -// indeed set. It's absence indicates that something changed in a way that -// is not supported by the client yet, in which case it must refuse to -// handle the request. message DeviceRequest { // Name can be used to reference this request in a pod.spec.containers[].resources.claims // entry and in a constraint of the claim. @@ -411,7 +535,10 @@ message DeviceRequest { // additional configuration and selectors to be inherited by this // request. // - // A class is required. Which classes are available depends on the cluster. + // A class is required if no subrequests are specified in the + // firstAvailable list and no class can be set if subrequests + // are specified in the firstAvailable list. + // Which classes are available depends on the cluster. // // Administrators may use this to restrict which devices may get // requested by only installing classes with selectors for permitted @@ -419,7 +546,8 @@ message DeviceRequest { // then administrators can create an empty DeviceClass for users // to reference. // - // +required + // +optional + // +oneOf=deviceRequestType optional string deviceClassName = 2; // Selectors define criteria which must be satisfied by a specific @@ -427,6 +555,9 @@ message DeviceRequest { // request. All selectors must be satisfied for a device to be // considered. // + // This field can only be set when deviceClassName is set and no subrequests + // are specified in the firstAvailable list. + // // +optional // +listType=atomic repeated DeviceSelector selectors = 3; @@ -439,13 +570,17 @@ message DeviceRequest { // count field. // // - All: This request is for all of the matching devices in a pool. + // At least one device must exist on the node for the allocation to succeed. // Allocation will fail if some devices are already allocated, // unless adminAccess is requested. // - // If AlloctionMode is not specified, the default mode is ExactCount. If + // If AllocationMode is not specified, the default mode is ExactCount. If // the mode is ExactCount and count is not specified, the default count is // one. Any other requests must specify this field. // + // This field can only be set when deviceClassName is set and no subrequests + // are specified in the firstAvailable list. + // // More modes may get added in the future. Clients must refuse to handle // requests with unknown modes. // @@ -455,6 +590,9 @@ message DeviceRequest { // Count is used only when the count mode is "ExactCount". Must be greater than zero. // If AllocationMode is ExactCount and this field is not specified, the default is one. // + // This field can only be set when deviceClassName is set and no subrequests + // are specified in the firstAvailable list. + // // +optional // +oneOf=AllocationMode optional int64 count = 5; @@ -465,6 +603,9 @@ message DeviceRequest { // all ordinary claims to the device with respect to access modes and // any resource allocations. // + // This field can only be set when deviceClassName is set and no subrequests + // are specified in the firstAvailable list. + // // This is an alpha field and requires enabling the DRAAdminAccess // feature gate. Admin access is disabled if this field is unset or // set to false, otherwise it is enabled. @@ -472,13 +613,65 @@ message DeviceRequest { // +optional // +featureGate=DRAAdminAccess optional bool adminAccess = 6; + + // FirstAvailable contains subrequests, of which exactly one will be + // satisfied by the scheduler to satisfy this request. It tries to + // satisfy them in the order in which they are listed here. So if + // there are two entries in the list, the scheduler will only check + // the second one if it determines that the first one cannot be used. + // + // This field may only be set in the entries of DeviceClaim.Requests. + // + // DRA does not yet implement scoring, so the scheduler will + // select the first set of devices that satisfies all the + // requests in the claim. And if the requirements can + // be satisfied on more than one node, other scheduling features + // will determine which node is chosen. This means that the set of + // devices allocated to a claim might not be the optimal set + // available to the cluster. Scoring will be implemented later. + // + // +optional + // +oneOf=deviceRequestType + // +listType=atomic + // +featureGate=DRAPrioritizedList + repeated DeviceSubRequest firstAvailable = 7; + + // If specified, the request's tolerations. + // + // Tolerations for NoSchedule are required to allocate a + // device which has a taint with that effect. The same applies + // to NoExecute. + // + // In addition, should any of the allocated devices get tainted + // with NoExecute after allocation and that effect is not tolerated, + // then all pods consuming the ResourceClaim get deleted to evict + // them. The scheduler will not let new pods reserve the claim while + // it has these tainted devices. Once all pods are evicted, the + // claim will get deallocated. + // + // The maximum number of tolerations is 16. + // + // This field can only be set when deviceClassName is set and no subrequests + // are specified in the firstAvailable list. + // + // This is an alpha field and requires enabling the DRADeviceTaints + // feature gate. + // + // +optional + // +listType=atomic + // +featureGate=DRADeviceTaints + repeated DeviceToleration tolerations = 8; } // DeviceRequestAllocationResult contains the allocation result for one request. message DeviceRequestAllocationResult { // Request is the name of the request in the claim which caused this - // device to be allocated. Multiple devices may have been allocated - // per request. + // device to be allocated. If it references a subrequest in the + // firstAvailable list on a DeviceRequest, this field must + // include both the name of the main request and the subrequest + // using the format
/. + // + // Multiple devices may have been allocated per request. // // +required optional string request = 1; @@ -519,6 +712,19 @@ message DeviceRequestAllocationResult { // +optional // +featureGate=DRAAdminAccess optional bool adminAccess = 5; + + // A copy of all tolerations specified in the request at the time + // when the device got allocated. + // + // The maximum number of tolerations is 16. + // + // This is an alpha field and requires enabling the DRADeviceTaints + // feature gate. + // + // +optional + // +listType=atomic + // +featureGate=DRADeviceTaints + repeated DeviceToleration tolerations = 6; } // DeviceSelector must have exactly one field set. @@ -530,6 +736,262 @@ message DeviceSelector { optional CELDeviceSelector cel = 1; } +// DeviceSubRequest describes a request for device provided in the +// claim.spec.devices.requests[].firstAvailable array. Each +// is typically a request for a single resource like a device, but can +// also ask for several identical devices. +// +// DeviceSubRequest is similar to Request, but doesn't expose the AdminAccess +// or FirstAvailable fields, as those can only be set on the top-level request. +// AdminAccess is not supported for requests with a prioritized list, and +// recursive FirstAvailable fields are not supported. +message DeviceSubRequest { + // Name can be used to reference this subrequest in the list of constraints + // or the list of configurations for the claim. References must use the + // format
/. + // + // Must be a DNS label. + // + // +required + optional string name = 1; + + // DeviceClassName references a specific DeviceClass, which can define + // additional configuration and selectors to be inherited by this + // subrequest. + // + // A class is required. Which classes are available depends on the cluster. + // + // Administrators may use this to restrict which devices may get + // requested by only installing classes with selectors for permitted + // devices. If users are free to request anything without restrictions, + // then administrators can create an empty DeviceClass for users + // to reference. + // + // +required + optional string deviceClassName = 2; + + // Selectors define criteria which must be satisfied by a specific + // device in order for that device to be considered for this + // request. All selectors must be satisfied for a device to be + // considered. + // + // +optional + // +listType=atomic + repeated DeviceSelector selectors = 3; + + // AllocationMode and its related fields define how devices are allocated + // to satisfy this request. Supported values are: + // + // - ExactCount: This request is for a specific number of devices. + // This is the default. The exact number is provided in the + // count field. + // + // - All: This request is for all of the matching devices in a pool. + // Allocation will fail if some devices are already allocated, + // unless adminAccess is requested. + // + // If AllocationMode is not specified, the default mode is ExactCount. If + // the mode is ExactCount and count is not specified, the default count is + // one. Any other requests must specify this field. + // + // More modes may get added in the future. Clients must refuse to handle + // requests with unknown modes. + // + // +optional + optional string allocationMode = 4; + + // Count is used only when the count mode is "ExactCount". Must be greater than zero. + // If AllocationMode is ExactCount and this field is not specified, the default is one. + // + // +optional + // +oneOf=AllocationMode + optional int64 count = 5; + + // If specified, the request's tolerations. + // + // Tolerations for NoSchedule are required to allocate a + // device which has a taint with that effect. The same applies + // to NoExecute. + // + // In addition, should any of the allocated devices get tainted + // with NoExecute after allocation and that effect is not tolerated, + // then all pods consuming the ResourceClaim get deleted to evict + // them. The scheduler will not let new pods reserve the claim while + // it has these tainted devices. Once all pods are evicted, the + // claim will get deallocated. + // + // The maximum number of tolerations is 16. + // + // This is an alpha field and requires enabling the DRADeviceTaints + // feature gate. + // + // +optional + // +listType=atomic + // +featureGate=DRADeviceTaints + repeated DeviceToleration tolerations = 7; +} + +// The device this taint is attached to has the "effect" on +// any claim which does not tolerate the taint and, through the claim, +// to pods using the claim. +message DeviceTaint { + // The taint key to be applied to a device. + // Must be a label name. + // + // +required + optional string key = 1; + + // The taint value corresponding to the taint key. + // Must be a label value. + // + // +optional + optional string value = 2; + + // The effect of the taint on claims that do not tolerate the taint + // and through such claims on the pods using them. + // Valid effects are NoSchedule and NoExecute. PreferNoSchedule as used for + // nodes is not valid here. + // + // +required + optional string effect = 3; + + // TimeAdded represents the time at which the taint was added. + // Added automatically during create or update if not set. + // + // +optional + optional .k8s.io.apimachinery.pkg.apis.meta.v1.Time timeAdded = 4; +} + +// DeviceTaintRule adds one taint to all devices which match the selector. +// This has the same effect as if the taint was specified directly +// in the ResourceSlice by the DRA driver. +message DeviceTaintRule { + // Standard object metadata + // +optional + optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; + + // Spec specifies the selector and one taint. + // + // Changing the spec automatically increments the metadata.generation number. + optional DeviceTaintRuleSpec spec = 2; +} + +// DeviceTaintRuleList is a collection of DeviceTaintRules. +message DeviceTaintRuleList { + // Standard list metadata + // +optional + optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; + + // Items is the list of DeviceTaintRules. + repeated DeviceTaintRule items = 2; +} + +// DeviceTaintRuleSpec specifies the selector and one taint. +message DeviceTaintRuleSpec { + // DeviceSelector defines which device(s) the taint is applied to. + // All selector criteria must be satified for a device to + // match. The empty selector matches all devices. Without + // a selector, no devices are matches. + // + // +optional + optional DeviceTaintSelector deviceSelector = 1; + + // The taint that gets applied to matching devices. + // + // +required + optional DeviceTaint taint = 2; +} + +// DeviceTaintSelector defines which device(s) a DeviceTaintRule applies to. +// The empty selector matches all devices. Without a selector, no devices +// are matched. +message DeviceTaintSelector { + // If DeviceClassName is set, the selectors defined there must be + // satisfied by a device to be selected. This field corresponds + // to class.metadata.name. + // + // +optional + optional string deviceClassName = 1; + + // If driver is set, only devices from that driver are selected. + // This fields corresponds to slice.spec.driver. + // + // +optional + optional string driver = 2; + + // If pool is set, only devices in that pool are selected. + // + // Also setting the driver name may be useful to avoid + // ambiguity when different drivers use the same pool name, + // but this is not required because selecting pools from + // different drivers may also be useful, for example when + // drivers with node-local devices use the node name as + // their pool name. + // + // +optional + optional string pool = 3; + + // If device is set, only devices with that name are selected. + // This field corresponds to slice.spec.devices[].name. + // + // Setting also driver and pool may be required to avoid ambiguity, + // but is not required. + // + // +optional + optional string device = 4; + + // Selectors contains the same selection criteria as a ResourceClaim. + // Currently, CEL expressions are supported. All of these selectors + // must be satisfied. + // + // +optional + // +listType=atomic + repeated DeviceSelector selectors = 5; +} + +// The ResourceClaim this DeviceToleration is attached to tolerates any taint that matches +// the triple using the matching operator . +message DeviceToleration { + // Key is the taint key that the toleration applies to. Empty means match all taint keys. + // If the key is empty, operator must be Exists; this combination means to match all values and all keys. + // Must be a label name. + // + // +optional + optional string key = 1; + + // Operator represents a key's relationship to the value. + // Valid operators are Exists and Equal. Defaults to Equal. + // Exists is equivalent to wildcard for value, so that a ResourceClaim can + // tolerate all taints of a particular category. + // + // +optional + // +default="Equal" + optional string operator = 2; + + // Value is the taint value the toleration matches to. + // If the operator is Exists, the value must be empty, otherwise just a regular string. + // Must be a label value. + // + // +optional + optional string value = 3; + + // Effect indicates the taint effect to match. Empty means match all taint effects. + // When specified, allowed values are NoSchedule and NoExecute. + // + // +optional + optional string effect = 4; + + // TolerationSeconds represents the period of time the toleration (which must be + // of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + // it is not set, which means tolerate the taint forever (do not evict). Zero and + // negative values will be treated as 0 (evict immediately) by the system. + // If larger than zero, the time when the pod needs to be evicted is calculated as
/. + // + // Must be a DNS label. + // + // +required + Name string `json:"name" protobuf:"bytes,1,name=name"` + + // DeviceClassName references a specific DeviceClass, which can define + // additional configuration and selectors to be inherited by this + // subrequest. + // + // A class is required. Which classes are available depends on the cluster. + // + // Administrators may use this to restrict which devices may get + // requested by only installing classes with selectors for permitted + // devices. If users are free to request anything without restrictions, + // then administrators can create an empty DeviceClass for users + // to reference. + // + // +required + DeviceClassName string `json:"deviceClassName" protobuf:"bytes,2,name=deviceClassName"` + + // Selectors define criteria which must be satisfied by a specific + // device in order for that device to be considered for this + // request. All selectors must be satisfied for a device to be + // considered. + // + // +optional + // +listType=atomic + Selectors []DeviceSelector `json:"selectors,omitempty" protobuf:"bytes,3,name=selectors"` + + // AllocationMode and its related fields define how devices are allocated + // to satisfy this request. Supported values are: + // + // - ExactCount: This request is for a specific number of devices. + // This is the default. The exact number is provided in the + // count field. + // + // - All: This request is for all of the matching devices in a pool. + // Allocation will fail if some devices are already allocated, + // unless adminAccess is requested. + // + // If AllocationMode is not specified, the default mode is ExactCount. If + // the mode is ExactCount and count is not specified, the default count is + // one. Any other requests must specify this field. + // + // More modes may get added in the future. Clients must refuse to handle + // requests with unknown modes. + // + // +optional + AllocationMode DeviceAllocationMode `json:"allocationMode,omitempty" protobuf:"bytes,4,opt,name=allocationMode"` + + // Count is used only when the count mode is "ExactCount". Must be greater than zero. + // If AllocationMode is ExactCount and this field is not specified, the default is one. + // + // +optional + // +oneOf=AllocationMode + Count int64 `json:"count,omitempty" protobuf:"bytes,5,opt,name=count"` + + // If specified, the request's tolerations. + // + // Tolerations for NoSchedule are required to allocate a + // device which has a taint with that effect. The same applies + // to NoExecute. + // + // In addition, should any of the allocated devices get tainted + // with NoExecute after allocation and that effect is not tolerated, + // then all pods consuming the ResourceClaim get deleted to evict + // them. The scheduler will not let new pods reserve the claim while + // it has these tainted devices. Once all pods are evicted, the + // claim will get deallocated. + // + // The maximum number of tolerations is 16. + // + // This is an alpha field and requires enabling the DRADeviceTaints + // feature gate. + // + // +optional + // +listType=atomic + // +featureGate=DRADeviceTaints + Tolerations []DeviceToleration `json:"tolerations,omitempty" protobuf:"bytes,7,opt,name=tolerations"` } const ( - DeviceSelectorsMaxSize = 32 + DeviceSelectorsMaxSize = 32 + FirstAvailableDeviceRequestMaxSize = 8 + DeviceTolerationsMaxLength = 16 ) type DeviceAllocationMode string @@ -581,6 +952,10 @@ type DeviceConstraint struct { // constraint. If this is not specified, this constraint applies to all // requests in this claim. // + // References to subrequests must include the name of the main request + // and may include the subrequest using the format
[/]. If just + // the main request is given, the constraint applies to all subrequests. + // // +optional // +listType=atomic Requests []string `json:"requests,omitempty" protobuf:"bytes,1,opt,name=requests"` @@ -618,6 +993,10 @@ type DeviceClaimConfiguration struct { // Requests lists the names of requests where the configuration applies. // If empty, it applies to all requests. // + // References to subrequests must include the name of the main request + // and may include the subrequest using the format
[/]. If just + // the main request is given, the configuration applies to all subrequests. + // // +optional // +listType=atomic Requests []string `json:"requests,omitempty" protobuf:"bytes,1,opt,name=requests"` @@ -666,6 +1045,59 @@ type OpaqueDeviceConfiguration struct { // [OpaqueDeviceConfiguration.Parameters] field. const OpaqueParametersMaxLength = 10 * 1024 +// The ResourceClaim this DeviceToleration is attached to tolerates any taint that matches +// the triple using the matching operator . +type DeviceToleration struct { + // Key is the taint key that the toleration applies to. Empty means match all taint keys. + // If the key is empty, operator must be Exists; this combination means to match all values and all keys. + // Must be a label name. + // + // +optional + Key string `json:"key,omitempty" protobuf:"bytes,1,opt,name=key"` + + // Operator represents a key's relationship to the value. + // Valid operators are Exists and Equal. Defaults to Equal. + // Exists is equivalent to wildcard for value, so that a ResourceClaim can + // tolerate all taints of a particular category. + // + // +optional + // +default="Equal" + Operator DeviceTolerationOperator `json:"operator,omitempty" protobuf:"bytes,2,opt,name=operator,casttype=DeviceTolerationOperator"` + + // Value is the taint value the toleration matches to. + // If the operator is Exists, the value must be empty, otherwise just a regular string. + // Must be a label value. + // + // +optional + Value string `json:"value,omitempty" protobuf:"bytes,3,opt,name=value"` + + // Effect indicates the taint effect to match. Empty means match all taint effects. + // When specified, allowed values are NoSchedule and NoExecute. + // + // +optional + Effect DeviceTaintEffect `json:"effect,omitempty" protobuf:"bytes,4,opt,name=effect,casttype=DeviceTaintEffect"` + + // TolerationSeconds represents the period of time the toleration (which must be + // of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + // it is not set, which means tolerate the taint forever (do not evict). Zero and + // negative values will be treated as 0 (evict immediately) by the system. + // If larger than zero, the time when the pod needs to be evicted is calculated as
/. + // + // Multiple devices may have been allocated per request. // // +required Request string `json:"request" protobuf:"bytes,1,name=request"` @@ -832,6 +1268,19 @@ type DeviceRequestAllocationResult struct { // +optional // +featureGate=DRAAdminAccess AdminAccess *bool `json:"adminAccess" protobuf:"bytes,5,name=adminAccess"` + + // A copy of all tolerations specified in the request at the time + // when the device got allocated. + // + // The maximum number of tolerations is 16. + // + // This is an alpha field and requires enabling the DRADeviceTaints + // feature gate. + // + // +optional + // +listType=atomic + // +featureGate=DRADeviceTaints + Tolerations []DeviceToleration `json:"tolerations,omitempty" protobuf:"bytes,6,opt,name=tolerations"` } // DeviceAllocationConfiguration gets embedded in an AllocationResult. @@ -846,6 +1295,10 @@ type DeviceAllocationConfiguration struct { // Requests lists the names of requests where the configuration applies. // If empty, its applies to all requests. // + // References to subrequests must include the name of the main request + // and may include the subrequest using the format
[/]. If just + // the main request is given, the configuration applies to all subrequests. + // // +optional // +listType=atomic Requests []string `json:"requests,omitempty" protobuf:"bytes,2,opt,name=requests"` @@ -1003,6 +1456,24 @@ type ResourceClaimTemplateList struct { Items []ResourceClaimTemplate `json:"items" protobuf:"bytes,2,rep,name=items"` } +const ( + // AllocatedDeviceStatusMaxConditions represents the maximum number of + // conditions in a device status. + AllocatedDeviceStatusMaxConditions int = 8 + // AllocatedDeviceStatusDataMaxLength represents the maximum length of the + // raw data in the Data field in a device status. + AllocatedDeviceStatusDataMaxLength int = 10 * 1024 + // NetworkDeviceDataMaxIPs represents the maximum number of IPs in the networkData + // field in a device status. + NetworkDeviceDataMaxIPs int = 16 + // NetworkDeviceDataInterfaceNameMaxLength represents the maximum number of characters + // for the networkData.interfaceName field in a device status. + NetworkDeviceDataInterfaceNameMaxLength int = 256 + // NetworkDeviceDataHardwareAddressMaxLength represents the maximum number of characters + // for the networkData.hardwareAddress field in a device status. + NetworkDeviceDataHardwareAddressMaxLength int = 128 +) + // AllocatedDeviceStatus contains the status of an allocated device, if the // driver chooses to report it. This may include driver-specific information. type AllocatedDeviceStatus struct { @@ -1035,6 +1506,8 @@ type AllocatedDeviceStatus struct { // If the device has been configured according to the class and claim // config references, the `Ready` condition should be True. // + // Must not contain more than 8 entries. + // // +optional // +listType=map // +listMapKey=type @@ -1045,7 +1518,7 @@ type AllocatedDeviceStatus struct { // The length of the raw data must be smaller or equal to 10 Ki. // // +optional - Data runtime.RawExtension `json:"data,omitempty" protobuf:"bytes,5,opt,name=data"` + Data *runtime.RawExtension `json:"data,omitempty" protobuf:"bytes,5,opt,name=data"` // NetworkData contains network-related information specific to the device. // @@ -1072,6 +1545,8 @@ type NetworkDeviceData struct { // associated subnet mask. // e.g.: "192.0.2.5/24" for IPv4 and "2001:db8::5/64" for IPv6. // + // Must not contain more than 16 entries. + // // +optional // +listType=atomic IPs []string `json:"ips,omitempty" protobuf:"bytes,2,opt,name=ips"` @@ -1083,3 +1558,107 @@ type NetworkDeviceData struct { // +optional HardwareAddress string `json:"hardwareAddress,omitempty" protobuf:"bytes,3,opt,name=hardwareAddress"` } + +// +genclient +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.33 + +// DeviceTaintRule adds one taint to all devices which match the selector. +// This has the same effect as if the taint was specified directly +// in the ResourceSlice by the DRA driver. +type DeviceTaintRule struct { + metav1.TypeMeta `json:",inline"` + // Standard object metadata + // +optional + metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // Spec specifies the selector and one taint. + // + // Changing the spec automatically increments the metadata.generation number. + Spec DeviceTaintRuleSpec `json:"spec" protobuf:"bytes,2,name=spec"` + + // ^^^ + // A spec gets added because adding a status seems likely. + // Such a status could provide feedback on applying the + // eviction and/or statistics (number of matching devices, + // affected allocated claims, pods remaining to be evicted, + // etc.). +} + +// DeviceTaintRuleSpec specifies the selector and one taint. +type DeviceTaintRuleSpec struct { + // DeviceSelector defines which device(s) the taint is applied to. + // All selector criteria must be satified for a device to + // match. The empty selector matches all devices. Without + // a selector, no devices are matches. + // + // +optional + DeviceSelector *DeviceTaintSelector `json:"deviceSelector,omitempty" protobuf:"bytes,1,opt,name=deviceSelector"` + + // The taint that gets applied to matching devices. + // + // +required + Taint DeviceTaint `json:"taint,omitempty" protobuf:"bytes,2,rep,name=taint"` +} + +// DeviceTaintSelector defines which device(s) a DeviceTaintRule applies to. +// The empty selector matches all devices. Without a selector, no devices +// are matched. +type DeviceTaintSelector struct { + // If DeviceClassName is set, the selectors defined there must be + // satisfied by a device to be selected. This field corresponds + // to class.metadata.name. + // + // +optional + DeviceClassName *string `json:"deviceClassName,omitempty" protobuf:"bytes,1,opt,name=deviceClassName"` + + // If driver is set, only devices from that driver are selected. + // This fields corresponds to slice.spec.driver. + // + // +optional + Driver *string `json:"driver,omitempty" protobuf:"bytes,2,opt,name=driver"` + + // If pool is set, only devices in that pool are selected. + // + // Also setting the driver name may be useful to avoid + // ambiguity when different drivers use the same pool name, + // but this is not required because selecting pools from + // different drivers may also be useful, for example when + // drivers with node-local devices use the node name as + // their pool name. + // + // +optional + Pool *string `json:"pool,omitempty" protobuf:"bytes,3,opt,name=pool"` + + // If device is set, only devices with that name are selected. + // This field corresponds to slice.spec.devices[].name. + // + // Setting also driver and pool may be required to avoid ambiguity, + // but is not required. + // + // +optional + Device *string `json:"device,omitempty" protobuf:"bytes,4,opt,name=device"` + + // Selectors contains the same selection criteria as a ResourceClaim. + // Currently, CEL expressions are supported. All of these selectors + // must be satisfied. + // + // +optional + // +listType=atomic + Selectors []DeviceSelector `json:"selectors,omitempty" protobuf:"bytes,5,rep,name=selectors"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:prerelease-lifecycle-gen:introduced=1.33 + +// DeviceTaintRuleList is a collection of DeviceTaintRules. +type DeviceTaintRuleList struct { + metav1.TypeMeta `json:",inline"` + // Standard list metadata + // +optional + metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + + // Items is the list of DeviceTaintRules. + Items []DeviceTaintRule `json:"items" protobuf:"bytes,2,rep,name=items"` +} diff --git a/go-controller/vendor/k8s.io/api/resource/v1alpha3/types_swagger_doc_generated.go b/go-controller/vendor/k8s.io/api/resource/v1alpha3/types_swagger_doc_generated.go index b41609d118..291cce7eba 100644 --- a/go-controller/vendor/k8s.io/api/resource/v1alpha3/types_swagger_doc_generated.go +++ b/go-controller/vendor/k8s.io/api/resource/v1alpha3/types_swagger_doc_generated.go @@ -32,7 +32,7 @@ var map_AllocatedDeviceStatus = map[string]string{ "driver": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", "pool": "This name together with the driver name and the device name field identify which device was allocated (`//`).\n\nMust not be longer than 253 characters and may contain one or more DNS sub-domains separated by slashes.", "device": "Device references one device instance via its name in the driver's resource pool. It must be a DNS label.", - "conditions": "Conditions contains the latest observation of the device's state. If the device has been configured according to the class and claim config references, the `Ready` condition should be True.", + "conditions": "Conditions contains the latest observation of the device's state. If the device has been configured according to the class and claim config references, the `Ready` condition should be True.\n\nMust not contain more than 8 entries.", "data": "Data contains arbitrary driver-specific data.\n\nThe length of the raw data must be smaller or equal to 10 Ki.", "networkData": "NetworkData contains network-related information specific to the device.", } @@ -52,9 +52,14 @@ func (AllocationResult) SwaggerDoc() map[string]string { } var map_BasicDevice = map[string]string{ - "": "BasicDevice defines one device instance.", - "attributes": "Attributes defines the set of attributes for this device. The name of each attribute must be unique in that set.\n\nThe maximum number of attributes and capacities combined is 32.", - "capacity": "Capacity defines the set of capacities for this device. The name of each capacity must be unique in that set.\n\nThe maximum number of attributes and capacities combined is 32.", + "": "BasicDevice defines one device instance.", + "attributes": "Attributes defines the set of attributes for this device. The name of each attribute must be unique in that set.\n\nThe maximum number of attributes and capacities combined is 32.", + "capacity": "Capacity defines the set of capacities for this device. The name of each capacity must be unique in that set.\n\nThe maximum number of attributes and capacities combined is 32.", + "consumesCounters": "ConsumesCounters defines a list of references to sharedCounters and the set of counters that the device will consume from those counter sets.\n\nThere can only be a single entry per counterSet.\n\nThe total number of device counter consumption entries must be <= 32. In addition, the total number in the entire ResourceSlice must be <= 1024 (for example, 64 devices with 16 counters each).", + "nodeName": "NodeName identifies the node where the device is available.\n\nMust only be set if Spec.PerDeviceNodeSelection is set to true. At most one of NodeName, NodeSelector and AllNodes can be set.", + "nodeSelector": "NodeSelector defines the nodes where the device is available.\n\nMust only be set if Spec.PerDeviceNodeSelection is set to true. At most one of NodeName, NodeSelector and AllNodes can be set.", + "allNodes": "AllNodes indicates that all nodes have access to the device.\n\nMust only be set if Spec.PerDeviceNodeSelection is set to true. At most one of NodeName, NodeSelector and AllNodes can be set.", + "taints": "If specified, these are the driver-defined taints.\n\nThe maximum number of taints is 4.\n\nThis is an alpha field and requires enabling the DRADeviceTaints feature gate.", } func (BasicDevice) SwaggerDoc() map[string]string { @@ -70,6 +75,25 @@ func (CELDeviceSelector) SwaggerDoc() map[string]string { return map_CELDeviceSelector } +var map_Counter = map[string]string{ + "": "Counter describes a quantity associated with a device.", + "value": "Value defines how much of a certain device counter is available.", +} + +func (Counter) SwaggerDoc() map[string]string { + return map_Counter +} + +var map_CounterSet = map[string]string{ + "": "CounterSet defines a named set of counters that are available to be used by devices defined in the ResourceSlice.\n\nThe counters are not allocatable by themselves, but can be referenced by devices. When a device is allocated, the portion of counters it uses will no longer be available for use by other devices.", + "name": "CounterSet is the name of the set from which the counters defined will be consumed.", + "counters": "Counters defines the counters that will be consumed by the device. The name of each counter must be unique in that set and must be a DNS label.\n\nTo ensure this uniqueness, capacities defined by the vendor must be listed without the driver name as domain prefix in their name. All others must be listed with their domain prefix.\n\nThe maximum number of counters is 32.", +} + +func (CounterSet) SwaggerDoc() map[string]string { + return map_CounterSet +} + var map_Device = map[string]string{ "": "Device represents one individual hardware instance that can be selected based on its attributes. Besides the name, exactly one field must be set.", "name": "Name is unique identifier among all devices managed by the driver in the pool. It must be a DNS label.", @@ -83,7 +107,7 @@ func (Device) SwaggerDoc() map[string]string { var map_DeviceAllocationConfiguration = map[string]string{ "": "DeviceAllocationConfiguration gets embedded in an AllocationResult.", "source": "Source records whether the configuration comes from a class and thus is not something that a normal user would have been able to set or from a claim.", - "requests": "Requests lists the names of requests where the configuration applies. If empty, its applies to all requests.", + "requests": "Requests lists the names of requests where the configuration applies. If empty, its applies to all requests.\n\nReferences to subrequests must include the name of the main request and may include the subrequest using the format
[/]. If just the main request is given, the configuration applies to all subrequests.", } func (DeviceAllocationConfiguration) SwaggerDoc() map[string]string { @@ -125,7 +149,7 @@ func (DeviceClaim) SwaggerDoc() map[string]string { var map_DeviceClaimConfiguration = map[string]string{ "": "DeviceClaimConfiguration is used for configuration parameters in DeviceClaim.", - "requests": "Requests lists the names of requests where the configuration applies. If empty, it applies to all requests.", + "requests": "Requests lists the names of requests where the configuration applies. If empty, it applies to all requests.\n\nReferences to subrequests must include the name of the main request and may include the subrequest using the format
[/]. If just the main request is given, the configuration applies to all subrequests.", } func (DeviceClaimConfiguration) SwaggerDoc() map[string]string { @@ -181,7 +205,7 @@ func (DeviceConfiguration) SwaggerDoc() map[string]string { var map_DeviceConstraint = map[string]string{ "": "DeviceConstraint must have exactly one field set besides Requests.", - "requests": "Requests is a list of the one or more requests in this claim which must co-satisfy this constraint. If a request is fulfilled by multiple devices, then all of the devices must satisfy the constraint. If this is not specified, this constraint applies to all requests in this claim.", + "requests": "Requests is a list of the one or more requests in this claim which must co-satisfy this constraint. If a request is fulfilled by multiple devices, then all of the devices must satisfy the constraint. If this is not specified, this constraint applies to all requests in this claim.\n\nReferences to subrequests must include the name of the main request and may include the subrequest using the format
[/]. If just the main request is given, the constraint applies to all subrequests.", "matchAttribute": "MatchAttribute requires that all devices in question have this attribute and that its type and value are the same across those devices.\n\nFor example, if you specified \"dra.example.com/numa\" (a hypothetical example!), then only devices in the same NUMA node will be chosen. A device which does not have that attribute will not be chosen. All devices should use a value of the same type for this attribute because that is part of its specification, but if one device doesn't, then it also will not be chosen.\n\nMust include the domain qualifier.", } @@ -189,14 +213,26 @@ func (DeviceConstraint) SwaggerDoc() map[string]string { return map_DeviceConstraint } +var map_DeviceCounterConsumption = map[string]string{ + "": "DeviceCounterConsumption defines a set of counters that a device will consume from a CounterSet.", + "counterSet": "CounterSet defines the set from which the counters defined will be consumed.", + "counters": "Counters defines the Counter that will be consumed by the device.\n\nThe maximum number counters in a device is 32. In addition, the maximum number of all counters in all devices is 1024 (for example, 64 devices with 16 counters each).", +} + +func (DeviceCounterConsumption) SwaggerDoc() map[string]string { + return map_DeviceCounterConsumption +} + var map_DeviceRequest = map[string]string{ - "": "DeviceRequest is a request for devices required for a claim. This is typically a request for a single resource like a device, but can also ask for several identical devices.\n\nA DeviceClassName is currently required. Clients must check that it is indeed set. It's absence indicates that something changed in a way that is not supported by the client yet, in which case it must refuse to handle the request.", + "": "DeviceRequest is a request for devices required for a claim. This is typically a request for a single resource like a device, but can also ask for several identical devices.", "name": "Name can be used to reference this request in a pod.spec.containers[].resources.claims entry and in a constraint of the claim.\n\nMust be a DNS label.", - "deviceClassName": "DeviceClassName references a specific DeviceClass, which can define additional configuration and selectors to be inherited by this request.\n\nA class is required. Which classes are available depends on the cluster.\n\nAdministrators may use this to restrict which devices may get requested by only installing classes with selectors for permitted devices. If users are free to request anything without restrictions, then administrators can create an empty DeviceClass for users to reference.", - "selectors": "Selectors define criteria which must be satisfied by a specific device in order for that device to be considered for this request. All selectors must be satisfied for a device to be considered.", - "allocationMode": "AllocationMode and its related fields define how devices are allocated to satisfy this request. Supported values are:\n\n- ExactCount: This request is for a specific number of devices.\n This is the default. The exact number is provided in the\n count field.\n\n- All: This request is for all of the matching devices in a pool.\n Allocation will fail if some devices are already allocated,\n unless adminAccess is requested.\n\nIf AlloctionMode is not specified, the default mode is ExactCount. If the mode is ExactCount and count is not specified, the default count is one. Any other requests must specify this field.\n\nMore modes may get added in the future. Clients must refuse to handle requests with unknown modes.", - "count": "Count is used only when the count mode is \"ExactCount\". Must be greater than zero. If AllocationMode is ExactCount and this field is not specified, the default is one.", - "adminAccess": "AdminAccess indicates that this is a claim for administrative access to the device(s). Claims with AdminAccess are expected to be used for monitoring or other management services for a device. They ignore all ordinary claims to the device with respect to access modes and any resource allocations.\n\nThis is an alpha field and requires enabling the DRAAdminAccess feature gate. Admin access is disabled if this field is unset or set to false, otherwise it is enabled.", + "deviceClassName": "DeviceClassName references a specific DeviceClass, which can define additional configuration and selectors to be inherited by this request.\n\nA class is required if no subrequests are specified in the firstAvailable list and no class can be set if subrequests are specified in the firstAvailable list. Which classes are available depends on the cluster.\n\nAdministrators may use this to restrict which devices may get requested by only installing classes with selectors for permitted devices. If users are free to request anything without restrictions, then administrators can create an empty DeviceClass for users to reference.", + "selectors": "Selectors define criteria which must be satisfied by a specific device in order for that device to be considered for this request. All selectors must be satisfied for a device to be considered.\n\nThis field can only be set when deviceClassName is set and no subrequests are specified in the firstAvailable list.", + "allocationMode": "AllocationMode and its related fields define how devices are allocated to satisfy this request. Supported values are:\n\n- ExactCount: This request is for a specific number of devices.\n This is the default. The exact number is provided in the\n count field.\n\n- All: This request is for all of the matching devices in a pool.\n At least one device must exist on the node for the allocation to succeed.\n Allocation will fail if some devices are already allocated,\n unless adminAccess is requested.\n\nIf AllocationMode is not specified, the default mode is ExactCount. If the mode is ExactCount and count is not specified, the default count is one. Any other requests must specify this field.\n\nThis field can only be set when deviceClassName is set and no subrequests are specified in the firstAvailable list.\n\nMore modes may get added in the future. Clients must refuse to handle requests with unknown modes.", + "count": "Count is used only when the count mode is \"ExactCount\". Must be greater than zero. If AllocationMode is ExactCount and this field is not specified, the default is one.\n\nThis field can only be set when deviceClassName is set and no subrequests are specified in the firstAvailable list.", + "adminAccess": "AdminAccess indicates that this is a claim for administrative access to the device(s). Claims with AdminAccess are expected to be used for monitoring or other management services for a device. They ignore all ordinary claims to the device with respect to access modes and any resource allocations.\n\nThis field can only be set when deviceClassName is set and no subrequests are specified in the firstAvailable list.\n\nThis is an alpha field and requires enabling the DRAAdminAccess feature gate. Admin access is disabled if this field is unset or set to false, otherwise it is enabled.", + "firstAvailable": "FirstAvailable contains subrequests, of which exactly one will be satisfied by the scheduler to satisfy this request. It tries to satisfy them in the order in which they are listed here. So if there are two entries in the list, the scheduler will only check the second one if it determines that the first one cannot be used.\n\nThis field may only be set in the entries of DeviceClaim.Requests.\n\nDRA does not yet implement scoring, so the scheduler will select the first set of devices that satisfies all the requests in the claim. And if the requirements can be satisfied on more than one node, other scheduling features will determine which node is chosen. This means that the set of devices allocated to a claim might not be the optimal set available to the cluster. Scoring will be implemented later.", + "tolerations": "If specified, the request's tolerations.\n\nTolerations for NoSchedule are required to allocate a device which has a taint with that effect. The same applies to NoExecute.\n\nIn addition, should any of the allocated devices get tainted with NoExecute after allocation and that effect is not tolerated, then all pods consuming the ResourceClaim get deleted to evict them. The scheduler will not let new pods reserve the claim while it has these tainted devices. Once all pods are evicted, the claim will get deallocated.\n\nThe maximum number of tolerations is 16.\n\nThis field can only be set when deviceClassName is set and no subrequests are specified in the firstAvailable list.\n\nThis is an alpha field and requires enabling the DRADeviceTaints feature gate.", } func (DeviceRequest) SwaggerDoc() map[string]string { @@ -205,11 +241,12 @@ func (DeviceRequest) SwaggerDoc() map[string]string { var map_DeviceRequestAllocationResult = map[string]string{ "": "DeviceRequestAllocationResult contains the allocation result for one request.", - "request": "Request is the name of the request in the claim which caused this device to be allocated. Multiple devices may have been allocated per request.", + "request": "Request is the name of the request in the claim which caused this device to be allocated. If it references a subrequest in the firstAvailable list on a DeviceRequest, this field must include both the name of the main request and the subrequest using the format
/.\n\nMultiple devices may have been allocated per request.", "driver": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", "pool": "This name together with the driver name and the device name field identify which device was allocated (`//`).\n\nMust not be longer than 253 characters and may contain one or more DNS sub-domains separated by slashes.", "device": "Device references one device instance via its name in the driver's resource pool. It must be a DNS label.", "adminAccess": "AdminAccess indicates that this device was allocated for administrative access. See the corresponding request field for a definition of mode.\n\nThis is an alpha field and requires enabling the DRAAdminAccess feature gate. Admin access is disabled if this field is unset or set to false, otherwise it is enabled.", + "tolerations": "A copy of all tolerations specified in the request at the time when the device got allocated.\n\nThe maximum number of tolerations is 16.\n\nThis is an alpha field and requires enabling the DRADeviceTaints feature gate.", } func (DeviceRequestAllocationResult) SwaggerDoc() map[string]string { @@ -225,10 +262,92 @@ func (DeviceSelector) SwaggerDoc() map[string]string { return map_DeviceSelector } +var map_DeviceSubRequest = map[string]string{ + "": "DeviceSubRequest describes a request for device provided in the claim.spec.devices.requests[].firstAvailable array. Each is typically a request for a single resource like a device, but can also ask for several identical devices.\n\nDeviceSubRequest is similar to Request, but doesn't expose the AdminAccess or FirstAvailable fields, as those can only be set on the top-level request. AdminAccess is not supported for requests with a prioritized list, and recursive FirstAvailable fields are not supported.", + "name": "Name can be used to reference this subrequest in the list of constraints or the list of configurations for the claim. References must use the format
/.\n\nMust be a DNS label.", + "deviceClassName": "DeviceClassName references a specific DeviceClass, which can define additional configuration and selectors to be inherited by this subrequest.\n\nA class is required. Which classes are available depends on the cluster.\n\nAdministrators may use this to restrict which devices may get requested by only installing classes with selectors for permitted devices. If users are free to request anything without restrictions, then administrators can create an empty DeviceClass for users to reference.", + "selectors": "Selectors define criteria which must be satisfied by a specific device in order for that device to be considered for this request. All selectors must be satisfied for a device to be considered.", + "allocationMode": "AllocationMode and its related fields define how devices are allocated to satisfy this request. Supported values are:\n\n- ExactCount: This request is for a specific number of devices.\n This is the default. The exact number is provided in the\n count field.\n\n- All: This request is for all of the matching devices in a pool.\n Allocation will fail if some devices are already allocated,\n unless adminAccess is requested.\n\nIf AllocationMode is not specified, the default mode is ExactCount. If the mode is ExactCount and count is not specified, the default count is one. Any other requests must specify this field.\n\nMore modes may get added in the future. Clients must refuse to handle requests with unknown modes.", + "count": "Count is used only when the count mode is \"ExactCount\". Must be greater than zero. If AllocationMode is ExactCount and this field is not specified, the default is one.", + "tolerations": "If specified, the request's tolerations.\n\nTolerations for NoSchedule are required to allocate a device which has a taint with that effect. The same applies to NoExecute.\n\nIn addition, should any of the allocated devices get tainted with NoExecute after allocation and that effect is not tolerated, then all pods consuming the ResourceClaim get deleted to evict them. The scheduler will not let new pods reserve the claim while it has these tainted devices. Once all pods are evicted, the claim will get deallocated.\n\nThe maximum number of tolerations is 16.\n\nThis is an alpha field and requires enabling the DRADeviceTaints feature gate.", +} + +func (DeviceSubRequest) SwaggerDoc() map[string]string { + return map_DeviceSubRequest +} + +var map_DeviceTaint = map[string]string{ + "": "The device this taint is attached to has the \"effect\" on any claim which does not tolerate the taint and, through the claim, to pods using the claim.", + "key": "The taint key to be applied to a device. Must be a label name.", + "value": "The taint value corresponding to the taint key. Must be a label value.", + "effect": "The effect of the taint on claims that do not tolerate the taint and through such claims on the pods using them. Valid effects are NoSchedule and NoExecute. PreferNoSchedule as used for nodes is not valid here.", + "timeAdded": "TimeAdded represents the time at which the taint was added. Added automatically during create or update if not set.", +} + +func (DeviceTaint) SwaggerDoc() map[string]string { + return map_DeviceTaint +} + +var map_DeviceTaintRule = map[string]string{ + "": "DeviceTaintRule adds one taint to all devices which match the selector. This has the same effect as if the taint was specified directly in the ResourceSlice by the DRA driver.", + "metadata": "Standard object metadata", + "spec": "Spec specifies the selector and one taint.\n\nChanging the spec automatically increments the metadata.generation number.", +} + +func (DeviceTaintRule) SwaggerDoc() map[string]string { + return map_DeviceTaintRule +} + +var map_DeviceTaintRuleList = map[string]string{ + "": "DeviceTaintRuleList is a collection of DeviceTaintRules.", + "metadata": "Standard list metadata", + "items": "Items is the list of DeviceTaintRules.", +} + +func (DeviceTaintRuleList) SwaggerDoc() map[string]string { + return map_DeviceTaintRuleList +} + +var map_DeviceTaintRuleSpec = map[string]string{ + "": "DeviceTaintRuleSpec specifies the selector and one taint.", + "deviceSelector": "DeviceSelector defines which device(s) the taint is applied to. All selector criteria must be satified for a device to match. The empty selector matches all devices. Without a selector, no devices are matches.", + "taint": "The taint that gets applied to matching devices.", +} + +func (DeviceTaintRuleSpec) SwaggerDoc() map[string]string { + return map_DeviceTaintRuleSpec +} + +var map_DeviceTaintSelector = map[string]string{ + "": "DeviceTaintSelector defines which device(s) a DeviceTaintRule applies to. The empty selector matches all devices. Without a selector, no devices are matched.", + "deviceClassName": "If DeviceClassName is set, the selectors defined there must be satisfied by a device to be selected. This field corresponds to class.metadata.name.", + "driver": "If driver is set, only devices from that driver are selected. This fields corresponds to slice.spec.driver.", + "pool": "If pool is set, only devices in that pool are selected.\n\nAlso setting the driver name may be useful to avoid ambiguity when different drivers use the same pool name, but this is not required because selecting pools from different drivers may also be useful, for example when drivers with node-local devices use the node name as their pool name.", + "device": "If device is set, only devices with that name are selected. This field corresponds to slice.spec.devices[].name.\n\nSetting also driver and pool may be required to avoid ambiguity, but is not required.", + "selectors": "Selectors contains the same selection criteria as a ResourceClaim. Currently, CEL expressions are supported. All of these selectors must be satisfied.", +} + +func (DeviceTaintSelector) SwaggerDoc() map[string]string { + return map_DeviceTaintSelector +} + +var map_DeviceToleration = map[string]string{ + "": "The ResourceClaim this DeviceToleration is attached to tolerates any taint that matches the triple using the matching operator .", + "key": "Key is the taint key that the toleration applies to. Empty means match all taint keys. If the key is empty, operator must be Exists; this combination means to match all values and all keys. Must be a label name.", + "operator": "Operator represents a key's relationship to the value. Valid operators are Exists and Equal. Defaults to Equal. Exists is equivalent to wildcard for value, so that a ResourceClaim can tolerate all taints of a particular category.", + "value": "Value is the taint value the toleration matches to. If the operator is Exists, the value must be empty, otherwise just a regular string. Must be a label value.", + "effect": "Effect indicates the taint effect to match. Empty means match all taint effects. When specified, allowed values are NoSchedule and NoExecute.", + "tolerationSeconds": "TolerationSeconds represents the period of time the toleration (which must be of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, it is not set, which means tolerate the taint forever (do not evict). Zero and negative values will be treated as 0 (evict immediately) by the system. If larger than zero, the time when the pod needs to be evicted is calculated as
[/]. If just + // the main request is given, the configuration applies to all subrequests. + // // +optional // +listType=atomic repeated string requests = 2; @@ -292,6 +389,10 @@ message DeviceClaimConfiguration { // Requests lists the names of requests where the configuration applies. // If empty, it applies to all requests. // + // References to subrequests must include the name of the main request + // and may include the subrequest using the format
[/]. If just + // the main request is given, the configuration applies to all subrequests. + // // +optional // +listType=atomic repeated string requests = 1; @@ -376,6 +477,10 @@ message DeviceConstraint { // constraint. If this is not specified, this constraint applies to all // requests in this claim. // + // References to subrequests must include the name of the main request + // and may include the subrequest using the format
[/]. If just + // the main request is given, the constraint applies to all subrequests. + // // +optional // +listType=atomic repeated string requests = 1; @@ -398,19 +503,35 @@ message DeviceConstraint { optional string matchAttribute = 2; } +// DeviceCounterConsumption defines a set of counters that +// a device will consume from a CounterSet. +message DeviceCounterConsumption { + // CounterSet is the name of the set from which the + // counters defined will be consumed. + // + // +required + optional string counterSet = 1; + + // Counters defines the counters that will be consumed by the device. + // + // The maximum number counters in a device is 32. + // In addition, the maximum number of all counters + // in all devices is 1024 (for example, 64 devices with + // 16 counters each). + // + // +required + map counters = 2; +} + // DeviceRequest is a request for devices required for a claim. // This is typically a request for a single resource like a device, but can // also ask for several identical devices. -// -// A DeviceClassName is currently required. Clients must check that it is -// indeed set. It's absence indicates that something changed in a way that -// is not supported by the client yet, in which case it must refuse to -// handle the request. message DeviceRequest { // Name can be used to reference this request in a pod.spec.containers[].resources.claims // entry and in a constraint of the claim. // - // Must be a DNS label. + // Must be a DNS label and unique among all DeviceRequests in a + // ResourceClaim. // // +required optional string name = 1; @@ -419,7 +540,10 @@ message DeviceRequest { // additional configuration and selectors to be inherited by this // request. // - // A class is required. Which classes are available depends on the cluster. + // A class is required if no subrequests are specified in the + // firstAvailable list and no class can be set if subrequests + // are specified in the firstAvailable list. + // Which classes are available depends on the cluster. // // Administrators may use this to restrict which devices may get // requested by only installing classes with selectors for permitted @@ -427,7 +551,8 @@ message DeviceRequest { // then administrators can create an empty DeviceClass for users // to reference. // - // +required + // +optional + // +oneOf=deviceRequestType optional string deviceClassName = 2; // Selectors define criteria which must be satisfied by a specific @@ -435,6 +560,9 @@ message DeviceRequest { // request. All selectors must be satisfied for a device to be // considered. // + // This field can only be set when deviceClassName is set and no subrequests + // are specified in the firstAvailable list. + // // +optional // +listType=atomic repeated DeviceSelector selectors = 3; @@ -447,13 +575,17 @@ message DeviceRequest { // count field. // // - All: This request is for all of the matching devices in a pool. + // At least one device must exist on the node for the allocation to succeed. // Allocation will fail if some devices are already allocated, // unless adminAccess is requested. // - // If AlloctionMode is not specified, the default mode is ExactCount. If + // If AllocationMode is not specified, the default mode is ExactCount. If // the mode is ExactCount and count is not specified, the default count is // one. Any other requests must specify this field. // + // This field can only be set when deviceClassName is set and no subrequests + // are specified in the firstAvailable list. + // // More modes may get added in the future. Clients must refuse to handle // requests with unknown modes. // @@ -463,6 +595,9 @@ message DeviceRequest { // Count is used only when the count mode is "ExactCount". Must be greater than zero. // If AllocationMode is ExactCount and this field is not specified, the default is one. // + // This field can only be set when deviceClassName is set and no subrequests + // are specified in the firstAvailable list. + // // +optional // +oneOf=AllocationMode optional int64 count = 5; @@ -473,6 +608,9 @@ message DeviceRequest { // all ordinary claims to the device with respect to access modes and // any resource allocations. // + // This field can only be set when deviceClassName is set and no subrequests + // are specified in the firstAvailable list. + // // This is an alpha field and requires enabling the DRAAdminAccess // feature gate. Admin access is disabled if this field is unset or // set to false, otherwise it is enabled. @@ -480,13 +618,65 @@ message DeviceRequest { // +optional // +featureGate=DRAAdminAccess optional bool adminAccess = 6; + + // FirstAvailable contains subrequests, of which exactly one will be + // satisfied by the scheduler to satisfy this request. It tries to + // satisfy them in the order in which they are listed here. So if + // there are two entries in the list, the scheduler will only check + // the second one if it determines that the first one cannot be used. + // + // This field may only be set in the entries of DeviceClaim.Requests. + // + // DRA does not yet implement scoring, so the scheduler will + // select the first set of devices that satisfies all the + // requests in the claim. And if the requirements can + // be satisfied on more than one node, other scheduling features + // will determine which node is chosen. This means that the set of + // devices allocated to a claim might not be the optimal set + // available to the cluster. Scoring will be implemented later. + // + // +optional + // +oneOf=deviceRequestType + // +listType=atomic + // +featureGate=DRAPrioritizedList + repeated DeviceSubRequest firstAvailable = 7; + + // If specified, the request's tolerations. + // + // Tolerations for NoSchedule are required to allocate a + // device which has a taint with that effect. The same applies + // to NoExecute. + // + // In addition, should any of the allocated devices get tainted + // with NoExecute after allocation and that effect is not tolerated, + // then all pods consuming the ResourceClaim get deleted to evict + // them. The scheduler will not let new pods reserve the claim while + // it has these tainted devices. Once all pods are evicted, the + // claim will get deallocated. + // + // The maximum number of tolerations is 16. + // + // This field can only be set when deviceClassName is set and no subrequests + // are specified in the firstAvailable list. + // + // This is an alpha field and requires enabling the DRADeviceTaints + // feature gate. + // + // +optional + // +listType=atomic + // +featureGate=DRADeviceTaints + repeated DeviceToleration tolerations = 8; } // DeviceRequestAllocationResult contains the allocation result for one request. message DeviceRequestAllocationResult { // Request is the name of the request in the claim which caused this - // device to be allocated. Multiple devices may have been allocated - // per request. + // device to be allocated. If it references a subrequest in the + // firstAvailable list on a DeviceRequest, this field must + // include both the name of the main request and the subrequest + // using the format
/. + // + // Multiple devices may have been allocated per request. // // +required optional string request = 1; @@ -527,6 +717,19 @@ message DeviceRequestAllocationResult { // +optional // +featureGate=DRAAdminAccess optional bool adminAccess = 5; + + // A copy of all tolerations specified in the request at the time + // when the device got allocated. + // + // The maximum number of tolerations is 16. + // + // This is an alpha field and requires enabling the DRADeviceTaints + // feature gate. + // + // +optional + // +listType=atomic + // +featureGate=DRADeviceTaints + repeated DeviceToleration tolerations = 6; } // DeviceSelector must have exactly one field set. @@ -538,6 +741,177 @@ message DeviceSelector { optional CELDeviceSelector cel = 1; } +// DeviceSubRequest describes a request for device provided in the +// claim.spec.devices.requests[].firstAvailable array. Each +// is typically a request for a single resource like a device, but can +// also ask for several identical devices. +// +// DeviceSubRequest is similar to Request, but doesn't expose the AdminAccess +// or FirstAvailable fields, as those can only be set on the top-level request. +// AdminAccess is not supported for requests with a prioritized list, and +// recursive FirstAvailable fields are not supported. +message DeviceSubRequest { + // Name can be used to reference this subrequest in the list of constraints + // or the list of configurations for the claim. References must use the + // format
/. + // + // Must be a DNS label. + // + // +required + optional string name = 1; + + // DeviceClassName references a specific DeviceClass, which can define + // additional configuration and selectors to be inherited by this + // subrequest. + // + // A class is required. Which classes are available depends on the cluster. + // + // Administrators may use this to restrict which devices may get + // requested by only installing classes with selectors for permitted + // devices. If users are free to request anything without restrictions, + // then administrators can create an empty DeviceClass for users + // to reference. + // + // +required + optional string deviceClassName = 2; + + // Selectors define criteria which must be satisfied by a specific + // device in order for that device to be considered for this + // subrequest. All selectors must be satisfied for a device to be + // considered. + // + // +optional + // +listType=atomic + repeated DeviceSelector selectors = 3; + + // AllocationMode and its related fields define how devices are allocated + // to satisfy this subrequest. Supported values are: + // + // - ExactCount: This request is for a specific number of devices. + // This is the default. The exact number is provided in the + // count field. + // + // - All: This subrequest is for all of the matching devices in a pool. + // Allocation will fail if some devices are already allocated, + // unless adminAccess is requested. + // + // If AllocationMode is not specified, the default mode is ExactCount. If + // the mode is ExactCount and count is not specified, the default count is + // one. Any other subrequests must specify this field. + // + // More modes may get added in the future. Clients must refuse to handle + // requests with unknown modes. + // + // +optional + optional string allocationMode = 4; + + // Count is used only when the count mode is "ExactCount". Must be greater than zero. + // If AllocationMode is ExactCount and this field is not specified, the default is one. + // + // +optional + // +oneOf=AllocationMode + optional int64 count = 5; + + // If specified, the request's tolerations. + // + // Tolerations for NoSchedule are required to allocate a + // device which has a taint with that effect. The same applies + // to NoExecute. + // + // In addition, should any of the allocated devices get tainted + // with NoExecute after allocation and that effect is not tolerated, + // then all pods consuming the ResourceClaim get deleted to evict + // them. The scheduler will not let new pods reserve the claim while + // it has these tainted devices. Once all pods are evicted, the + // claim will get deallocated. + // + // The maximum number of tolerations is 16. + // + // This is an alpha field and requires enabling the DRADeviceTaints + // feature gate. + // + // +optional + // +listType=atomic + // +featureGate=DRADeviceTaints + repeated DeviceToleration tolerations = 7; +} + +// The device this taint is attached to has the "effect" on +// any claim which does not tolerate the taint and, through the claim, +// to pods using the claim. +// +// +protobuf.options.(gogoproto.goproto_stringer)=false +message DeviceTaint { + // The taint key to be applied to a device. + // Must be a label name. + // + // +required + optional string key = 1; + + // The taint value corresponding to the taint key. + // Must be a label value. + // + // +optional + optional string value = 2; + + // The effect of the taint on claims that do not tolerate the taint + // and through such claims on the pods using them. + // Valid effects are NoSchedule and NoExecute. PreferNoSchedule as used for + // nodes is not valid here. + // + // +required + optional string effect = 3; + + // TimeAdded represents the time at which the taint was added. + // Added automatically during create or update if not set. + // + // +optional + optional .k8s.io.apimachinery.pkg.apis.meta.v1.Time timeAdded = 4; +} + +// The ResourceClaim this DeviceToleration is attached to tolerates any taint that matches +// the triple using the matching operator . +message DeviceToleration { + // Key is the taint key that the toleration applies to. Empty means match all taint keys. + // If the key is empty, operator must be Exists; this combination means to match all values and all keys. + // Must be a label name. + // + // +optional + optional string key = 1; + + // Operator represents a key's relationship to the value. + // Valid operators are Exists and Equal. Defaults to Equal. + // Exists is equivalent to wildcard for value, so that a ResourceClaim can + // tolerate all taints of a particular category. + // + // +optional + // +default="Equal" + optional string operator = 2; + + // Value is the taint value the toleration matches to. + // If the operator is Exists, the value must be empty, otherwise just a regular string. + // Must be a label value. + // + // +optional + optional string value = 3; + + // Effect indicates the taint effect to match. Empty means match all taint effects. + // When specified, allowed values are NoSchedule and NoExecute. + // + // +optional + optional string effect = 4; + + // TolerationSeconds represents the period of time the toleration (which must be + // of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + // it is not set, which means tolerate the taint forever (do not evict). Zero and + // negative values will be treated as 0 (evict immediately) by the system. + // If larger than zero, the time when the pod needs to be evicted is calculated as
/. + // + // Must be a DNS label. + // + // +required + Name string `json:"name" protobuf:"bytes,1,name=name"` + + // DeviceClassName references a specific DeviceClass, which can define + // additional configuration and selectors to be inherited by this + // subrequest. + // + // A class is required. Which classes are available depends on the cluster. + // + // Administrators may use this to restrict which devices may get + // requested by only installing classes with selectors for permitted + // devices. If users are free to request anything without restrictions, + // then administrators can create an empty DeviceClass for users + // to reference. + // + // +required + DeviceClassName string `json:"deviceClassName" protobuf:"bytes,2,name=deviceClassName"` + + // Selectors define criteria which must be satisfied by a specific + // device in order for that device to be considered for this + // subrequest. All selectors must be satisfied for a device to be + // considered. + // + // +optional + // +listType=atomic + Selectors []DeviceSelector `json:"selectors,omitempty" protobuf:"bytes,3,name=selectors"` + + // AllocationMode and its related fields define how devices are allocated + // to satisfy this subrequest. Supported values are: + // + // - ExactCount: This request is for a specific number of devices. + // This is the default. The exact number is provided in the + // count field. + // + // - All: This subrequest is for all of the matching devices in a pool. + // Allocation will fail if some devices are already allocated, + // unless adminAccess is requested. + // + // If AllocationMode is not specified, the default mode is ExactCount. If + // the mode is ExactCount and count is not specified, the default count is + // one. Any other subrequests must specify this field. + // + // More modes may get added in the future. Clients must refuse to handle + // requests with unknown modes. + // + // +optional + AllocationMode DeviceAllocationMode `json:"allocationMode,omitempty" protobuf:"bytes,4,opt,name=allocationMode"` + + // Count is used only when the count mode is "ExactCount". Must be greater than zero. + // If AllocationMode is ExactCount and this field is not specified, the default is one. + // + // +optional + // +oneOf=AllocationMode + Count int64 `json:"count,omitempty" protobuf:"bytes,5,opt,name=count"` + + // If specified, the request's tolerations. + // + // Tolerations for NoSchedule are required to allocate a + // device which has a taint with that effect. The same applies + // to NoExecute. + // + // In addition, should any of the allocated devices get tainted + // with NoExecute after allocation and that effect is not tolerated, + // then all pods consuming the ResourceClaim get deleted to evict + // them. The scheduler will not let new pods reserve the claim while + // it has these tainted devices. Once all pods are evicted, the + // claim will get deallocated. + // + // The maximum number of tolerations is 16. + // + // This is an alpha field and requires enabling the DRADeviceTaints + // feature gate. + // + // +optional + // +listType=atomic + // +featureGate=DRADeviceTaints + Tolerations []DeviceToleration `json:"tolerations,omitempty" protobuf:"bytes,7,opt,name=tolerations"` } const ( - DeviceSelectorsMaxSize = 32 + DeviceSelectorsMaxSize = 32 + FirstAvailableDeviceRequestMaxSize = 8 + DeviceTolerationsMaxLength = 16 ) type DeviceAllocationMode string @@ -589,6 +959,10 @@ type DeviceConstraint struct { // constraint. If this is not specified, this constraint applies to all // requests in this claim. // + // References to subrequests must include the name of the main request + // and may include the subrequest using the format
[/]. If just + // the main request is given, the constraint applies to all subrequests. + // // +optional // +listType=atomic Requests []string `json:"requests,omitempty" protobuf:"bytes,1,opt,name=requests"` @@ -626,6 +1000,10 @@ type DeviceClaimConfiguration struct { // Requests lists the names of requests where the configuration applies. // If empty, it applies to all requests. // + // References to subrequests must include the name of the main request + // and may include the subrequest using the format
[/]. If just + // the main request is given, the configuration applies to all subrequests. + // // +optional // +listType=atomic Requests []string `json:"requests,omitempty" protobuf:"bytes,1,opt,name=requests"` @@ -674,6 +1052,59 @@ type OpaqueDeviceConfiguration struct { // [OpaqueDeviceConfiguration.Parameters] field. const OpaqueParametersMaxLength = 10 * 1024 +// The ResourceClaim this DeviceToleration is attached to tolerates any taint that matches +// the triple using the matching operator . +type DeviceToleration struct { + // Key is the taint key that the toleration applies to. Empty means match all taint keys. + // If the key is empty, operator must be Exists; this combination means to match all values and all keys. + // Must be a label name. + // + // +optional + Key string `json:"key,omitempty" protobuf:"bytes,1,opt,name=key"` + + // Operator represents a key's relationship to the value. + // Valid operators are Exists and Equal. Defaults to Equal. + // Exists is equivalent to wildcard for value, so that a ResourceClaim can + // tolerate all taints of a particular category. + // + // +optional + // +default="Equal" + Operator DeviceTolerationOperator `json:"operator,omitempty" protobuf:"bytes,2,opt,name=operator,casttype=DeviceTolerationOperator"` + + // Value is the taint value the toleration matches to. + // If the operator is Exists, the value must be empty, otherwise just a regular string. + // Must be a label value. + // + // +optional + Value string `json:"value,omitempty" protobuf:"bytes,3,opt,name=value"` + + // Effect indicates the taint effect to match. Empty means match all taint effects. + // When specified, allowed values are NoSchedule and NoExecute. + // + // +optional + Effect DeviceTaintEffect `json:"effect,omitempty" protobuf:"bytes,4,opt,name=effect,casttype=DeviceTaintEffect"` + + // TolerationSeconds represents the period of time the toleration (which must be + // of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + // it is not set, which means tolerate the taint forever (do not evict). Zero and + // negative values will be treated as 0 (evict immediately) by the system. + // If larger than zero, the time when the pod needs to be evicted is calculated as
/. + // + // Multiple devices may have been allocated per request. // // +required Request string `json:"request" protobuf:"bytes,1,name=request"` @@ -840,6 +1275,19 @@ type DeviceRequestAllocationResult struct { // +optional // +featureGate=DRAAdminAccess AdminAccess *bool `json:"adminAccess" protobuf:"bytes,5,name=adminAccess"` + + // A copy of all tolerations specified in the request at the time + // when the device got allocated. + // + // The maximum number of tolerations is 16. + // + // This is an alpha field and requires enabling the DRADeviceTaints + // feature gate. + // + // +optional + // +listType=atomic + // +featureGate=DRADeviceTaints + Tolerations []DeviceToleration `json:"tolerations,omitempty" protobuf:"bytes,6,opt,name=tolerations"` } // DeviceAllocationConfiguration gets embedded in an AllocationResult. @@ -854,6 +1302,10 @@ type DeviceAllocationConfiguration struct { // Requests lists the names of requests where the configuration applies. // If empty, its applies to all requests. // + // References to subrequests must include the name of the main request + // and may include the subrequest using the format
[/]. If just + // the main request is given, the configuration applies to all subrequests. + // // +optional // +listType=atomic Requests []string `json:"requests,omitempty" protobuf:"bytes,2,opt,name=requests"` @@ -1006,6 +1458,24 @@ type ResourceClaimTemplateList struct { Items []ResourceClaimTemplate `json:"items" protobuf:"bytes,2,rep,name=items"` } +const ( + // AllocatedDeviceStatusMaxConditions represents the maximum number of + // conditions in a device status. + AllocatedDeviceStatusMaxConditions int = 8 + // AllocatedDeviceStatusDataMaxLength represents the maximum length of the + // raw data in the Data field in a device status. + AllocatedDeviceStatusDataMaxLength int = 10 * 1024 + // NetworkDeviceDataMaxIPs represents the maximum number of IPs in the networkData + // field in a device status. + NetworkDeviceDataMaxIPs int = 16 + // NetworkDeviceDataInterfaceNameMaxLength represents the maximum number of characters + // for the networkData.interfaceName field in a device status. + NetworkDeviceDataInterfaceNameMaxLength int = 256 + // NetworkDeviceDataHardwareAddressMaxLength represents the maximum number of characters + // for the networkData.hardwareAddress field in a device status. + NetworkDeviceDataHardwareAddressMaxLength int = 128 +) + // AllocatedDeviceStatus contains the status of an allocated device, if the // driver chooses to report it. This may include driver-specific information. type AllocatedDeviceStatus struct { @@ -1038,6 +1508,8 @@ type AllocatedDeviceStatus struct { // If the device has been configured according to the class and claim // config references, the `Ready` condition should be True. // + // Must not contain more than 8 entries. + // // +optional // +listType=map // +listMapKey=type @@ -1048,7 +1520,7 @@ type AllocatedDeviceStatus struct { // The length of the raw data must be smaller or equal to 10 Ki. // // +optional - Data runtime.RawExtension `json:"data,omitempty" protobuf:"bytes,5,opt,name=data"` + Data *runtime.RawExtension `json:"data,omitempty" protobuf:"bytes,5,opt,name=data"` // NetworkData contains network-related information specific to the device. // @@ -1075,6 +1547,8 @@ type NetworkDeviceData struct { // associated subnet mask. // e.g.: "192.0.2.5/24" for IPv4 and "2001:db8::5/64" for IPv6. // + // Must not contain more than 16 entries. + // // +optional // +listType=atomic IPs []string `json:"ips,omitempty" protobuf:"bytes,2,opt,name=ips"` diff --git a/go-controller/vendor/k8s.io/api/resource/v1beta1/types_swagger_doc_generated.go b/go-controller/vendor/k8s.io/api/resource/v1beta1/types_swagger_doc_generated.go index 4ecc35d08a..cd8b15fe3a 100644 --- a/go-controller/vendor/k8s.io/api/resource/v1beta1/types_swagger_doc_generated.go +++ b/go-controller/vendor/k8s.io/api/resource/v1beta1/types_swagger_doc_generated.go @@ -32,7 +32,7 @@ var map_AllocatedDeviceStatus = map[string]string{ "driver": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", "pool": "This name together with the driver name and the device name field identify which device was allocated (`//`).\n\nMust not be longer than 253 characters and may contain one or more DNS sub-domains separated by slashes.", "device": "Device references one device instance via its name in the driver's resource pool. It must be a DNS label.", - "conditions": "Conditions contains the latest observation of the device's state. If the device has been configured according to the class and claim config references, the `Ready` condition should be True.", + "conditions": "Conditions contains the latest observation of the device's state. If the device has been configured according to the class and claim config references, the `Ready` condition should be True.\n\nMust not contain more than 8 entries.", "data": "Data contains arbitrary driver-specific data.\n\nThe length of the raw data must be smaller or equal to 10 Ki.", "networkData": "NetworkData contains network-related information specific to the device.", } @@ -52,9 +52,14 @@ func (AllocationResult) SwaggerDoc() map[string]string { } var map_BasicDevice = map[string]string{ - "": "BasicDevice defines one device instance.", - "attributes": "Attributes defines the set of attributes for this device. The name of each attribute must be unique in that set.\n\nThe maximum number of attributes and capacities combined is 32.", - "capacity": "Capacity defines the set of capacities for this device. The name of each capacity must be unique in that set.\n\nThe maximum number of attributes and capacities combined is 32.", + "": "BasicDevice defines one device instance.", + "attributes": "Attributes defines the set of attributes for this device. The name of each attribute must be unique in that set.\n\nThe maximum number of attributes and capacities combined is 32.", + "capacity": "Capacity defines the set of capacities for this device. The name of each capacity must be unique in that set.\n\nThe maximum number of attributes and capacities combined is 32.", + "consumesCounters": "ConsumesCounters defines a list of references to sharedCounters and the set of counters that the device will consume from those counter sets.\n\nThere can only be a single entry per counterSet.\n\nThe total number of device counter consumption entries must be <= 32. In addition, the total number in the entire ResourceSlice must be <= 1024 (for example, 64 devices with 16 counters each).", + "nodeName": "NodeName identifies the node where the device is available.\n\nMust only be set if Spec.PerDeviceNodeSelection is set to true. At most one of NodeName, NodeSelector and AllNodes can be set.", + "nodeSelector": "NodeSelector defines the nodes where the device is available.\n\nMust use exactly one term.\n\nMust only be set if Spec.PerDeviceNodeSelection is set to true. At most one of NodeName, NodeSelector and AllNodes can be set.", + "allNodes": "AllNodes indicates that all nodes have access to the device.\n\nMust only be set if Spec.PerDeviceNodeSelection is set to true. At most one of NodeName, NodeSelector and AllNodes can be set.", + "taints": "If specified, these are the driver-defined taints.\n\nThe maximum number of taints is 4.\n\nThis is an alpha field and requires enabling the DRADeviceTaints feature gate.", } func (BasicDevice) SwaggerDoc() map[string]string { @@ -70,6 +75,25 @@ func (CELDeviceSelector) SwaggerDoc() map[string]string { return map_CELDeviceSelector } +var map_Counter = map[string]string{ + "": "Counter describes a quantity associated with a device.", + "value": "Value defines how much of a certain device counter is available.", +} + +func (Counter) SwaggerDoc() map[string]string { + return map_Counter +} + +var map_CounterSet = map[string]string{ + "": "CounterSet defines a named set of counters that are available to be used by devices defined in the ResourceSlice.\n\nThe counters are not allocatable by themselves, but can be referenced by devices. When a device is allocated, the portion of counters it uses will no longer be available for use by other devices.", + "name": "Name defines the name of the counter set. It must be a DNS label.", + "counters": "Counters defines the set of counters for this CounterSet The name of each counter must be unique in that set and must be a DNS label.\n\nThe maximum number of counters is 32.", +} + +func (CounterSet) SwaggerDoc() map[string]string { + return map_CounterSet +} + var map_Device = map[string]string{ "": "Device represents one individual hardware instance that can be selected based on its attributes. Besides the name, exactly one field must be set.", "name": "Name is unique identifier among all devices managed by the driver in the pool. It must be a DNS label.", @@ -83,7 +107,7 @@ func (Device) SwaggerDoc() map[string]string { var map_DeviceAllocationConfiguration = map[string]string{ "": "DeviceAllocationConfiguration gets embedded in an AllocationResult.", "source": "Source records whether the configuration comes from a class and thus is not something that a normal user would have been able to set or from a claim.", - "requests": "Requests lists the names of requests where the configuration applies. If empty, its applies to all requests.", + "requests": "Requests lists the names of requests where the configuration applies. If empty, its applies to all requests.\n\nReferences to subrequests must include the name of the main request and may include the subrequest using the format
[/]. If just the main request is given, the configuration applies to all subrequests.", } func (DeviceAllocationConfiguration) SwaggerDoc() map[string]string { @@ -134,7 +158,7 @@ func (DeviceClaim) SwaggerDoc() map[string]string { var map_DeviceClaimConfiguration = map[string]string{ "": "DeviceClaimConfiguration is used for configuration parameters in DeviceClaim.", - "requests": "Requests lists the names of requests where the configuration applies. If empty, it applies to all requests.", + "requests": "Requests lists the names of requests where the configuration applies. If empty, it applies to all requests.\n\nReferences to subrequests must include the name of the main request and may include the subrequest using the format
[/]. If just the main request is given, the configuration applies to all subrequests.", } func (DeviceClaimConfiguration) SwaggerDoc() map[string]string { @@ -190,7 +214,7 @@ func (DeviceConfiguration) SwaggerDoc() map[string]string { var map_DeviceConstraint = map[string]string{ "": "DeviceConstraint must have exactly one field set besides Requests.", - "requests": "Requests is a list of the one or more requests in this claim which must co-satisfy this constraint. If a request is fulfilled by multiple devices, then all of the devices must satisfy the constraint. If this is not specified, this constraint applies to all requests in this claim.", + "requests": "Requests is a list of the one or more requests in this claim which must co-satisfy this constraint. If a request is fulfilled by multiple devices, then all of the devices must satisfy the constraint. If this is not specified, this constraint applies to all requests in this claim.\n\nReferences to subrequests must include the name of the main request and may include the subrequest using the format
[/]. If just the main request is given, the constraint applies to all subrequests.", "matchAttribute": "MatchAttribute requires that all devices in question have this attribute and that its type and value are the same across those devices.\n\nFor example, if you specified \"dra.example.com/numa\" (a hypothetical example!), then only devices in the same NUMA node will be chosen. A device which does not have that attribute will not be chosen. All devices should use a value of the same type for this attribute because that is part of its specification, but if one device doesn't, then it also will not be chosen.\n\nMust include the domain qualifier.", } @@ -198,14 +222,26 @@ func (DeviceConstraint) SwaggerDoc() map[string]string { return map_DeviceConstraint } +var map_DeviceCounterConsumption = map[string]string{ + "": "DeviceCounterConsumption defines a set of counters that a device will consume from a CounterSet.", + "counterSet": "CounterSet is the name of the set from which the counters defined will be consumed.", + "counters": "Counters defines the counters that will be consumed by the device.\n\nThe maximum number counters in a device is 32. In addition, the maximum number of all counters in all devices is 1024 (for example, 64 devices with 16 counters each).", +} + +func (DeviceCounterConsumption) SwaggerDoc() map[string]string { + return map_DeviceCounterConsumption +} + var map_DeviceRequest = map[string]string{ - "": "DeviceRequest is a request for devices required for a claim. This is typically a request for a single resource like a device, but can also ask for several identical devices.\n\nA DeviceClassName is currently required. Clients must check that it is indeed set. It's absence indicates that something changed in a way that is not supported by the client yet, in which case it must refuse to handle the request.", - "name": "Name can be used to reference this request in a pod.spec.containers[].resources.claims entry and in a constraint of the claim.\n\nMust be a DNS label.", - "deviceClassName": "DeviceClassName references a specific DeviceClass, which can define additional configuration and selectors to be inherited by this request.\n\nA class is required. Which classes are available depends on the cluster.\n\nAdministrators may use this to restrict which devices may get requested by only installing classes with selectors for permitted devices. If users are free to request anything without restrictions, then administrators can create an empty DeviceClass for users to reference.", - "selectors": "Selectors define criteria which must be satisfied by a specific device in order for that device to be considered for this request. All selectors must be satisfied for a device to be considered.", - "allocationMode": "AllocationMode and its related fields define how devices are allocated to satisfy this request. Supported values are:\n\n- ExactCount: This request is for a specific number of devices.\n This is the default. The exact number is provided in the\n count field.\n\n- All: This request is for all of the matching devices in a pool.\n Allocation will fail if some devices are already allocated,\n unless adminAccess is requested.\n\nIf AlloctionMode is not specified, the default mode is ExactCount. If the mode is ExactCount and count is not specified, the default count is one. Any other requests must specify this field.\n\nMore modes may get added in the future. Clients must refuse to handle requests with unknown modes.", - "count": "Count is used only when the count mode is \"ExactCount\". Must be greater than zero. If AllocationMode is ExactCount and this field is not specified, the default is one.", - "adminAccess": "AdminAccess indicates that this is a claim for administrative access to the device(s). Claims with AdminAccess are expected to be used for monitoring or other management services for a device. They ignore all ordinary claims to the device with respect to access modes and any resource allocations.\n\nThis is an alpha field and requires enabling the DRAAdminAccess feature gate. Admin access is disabled if this field is unset or set to false, otherwise it is enabled.", + "": "DeviceRequest is a request for devices required for a claim. This is typically a request for a single resource like a device, but can also ask for several identical devices.", + "name": "Name can be used to reference this request in a pod.spec.containers[].resources.claims entry and in a constraint of the claim.\n\nMust be a DNS label and unique among all DeviceRequests in a ResourceClaim.", + "deviceClassName": "DeviceClassName references a specific DeviceClass, which can define additional configuration and selectors to be inherited by this request.\n\nA class is required if no subrequests are specified in the firstAvailable list and no class can be set if subrequests are specified in the firstAvailable list. Which classes are available depends on the cluster.\n\nAdministrators may use this to restrict which devices may get requested by only installing classes with selectors for permitted devices. If users are free to request anything without restrictions, then administrators can create an empty DeviceClass for users to reference.", + "selectors": "Selectors define criteria which must be satisfied by a specific device in order for that device to be considered for this request. All selectors must be satisfied for a device to be considered.\n\nThis field can only be set when deviceClassName is set and no subrequests are specified in the firstAvailable list.", + "allocationMode": "AllocationMode and its related fields define how devices are allocated to satisfy this request. Supported values are:\n\n- ExactCount: This request is for a specific number of devices.\n This is the default. The exact number is provided in the\n count field.\n\n- All: This request is for all of the matching devices in a pool.\n At least one device must exist on the node for the allocation to succeed.\n Allocation will fail if some devices are already allocated,\n unless adminAccess is requested.\n\nIf AllocationMode is not specified, the default mode is ExactCount. If the mode is ExactCount and count is not specified, the default count is one. Any other requests must specify this field.\n\nThis field can only be set when deviceClassName is set and no subrequests are specified in the firstAvailable list.\n\nMore modes may get added in the future. Clients must refuse to handle requests with unknown modes.", + "count": "Count is used only when the count mode is \"ExactCount\". Must be greater than zero. If AllocationMode is ExactCount and this field is not specified, the default is one.\n\nThis field can only be set when deviceClassName is set and no subrequests are specified in the firstAvailable list.", + "adminAccess": "AdminAccess indicates that this is a claim for administrative access to the device(s). Claims with AdminAccess are expected to be used for monitoring or other management services for a device. They ignore all ordinary claims to the device with respect to access modes and any resource allocations.\n\nThis field can only be set when deviceClassName is set and no subrequests are specified in the firstAvailable list.\n\nThis is an alpha field and requires enabling the DRAAdminAccess feature gate. Admin access is disabled if this field is unset or set to false, otherwise it is enabled.", + "firstAvailable": "FirstAvailable contains subrequests, of which exactly one will be satisfied by the scheduler to satisfy this request. It tries to satisfy them in the order in which they are listed here. So if there are two entries in the list, the scheduler will only check the second one if it determines that the first one cannot be used.\n\nThis field may only be set in the entries of DeviceClaim.Requests.\n\nDRA does not yet implement scoring, so the scheduler will select the first set of devices that satisfies all the requests in the claim. And if the requirements can be satisfied on more than one node, other scheduling features will determine which node is chosen. This means that the set of devices allocated to a claim might not be the optimal set available to the cluster. Scoring will be implemented later.", + "tolerations": "If specified, the request's tolerations.\n\nTolerations for NoSchedule are required to allocate a device which has a taint with that effect. The same applies to NoExecute.\n\nIn addition, should any of the allocated devices get tainted with NoExecute after allocation and that effect is not tolerated, then all pods consuming the ResourceClaim get deleted to evict them. The scheduler will not let new pods reserve the claim while it has these tainted devices. Once all pods are evicted, the claim will get deallocated.\n\nThe maximum number of tolerations is 16.\n\nThis field can only be set when deviceClassName is set and no subrequests are specified in the firstAvailable list.\n\nThis is an alpha field and requires enabling the DRADeviceTaints feature gate.", } func (DeviceRequest) SwaggerDoc() map[string]string { @@ -214,11 +250,12 @@ func (DeviceRequest) SwaggerDoc() map[string]string { var map_DeviceRequestAllocationResult = map[string]string{ "": "DeviceRequestAllocationResult contains the allocation result for one request.", - "request": "Request is the name of the request in the claim which caused this device to be allocated. Multiple devices may have been allocated per request.", + "request": "Request is the name of the request in the claim which caused this device to be allocated. If it references a subrequest in the firstAvailable list on a DeviceRequest, this field must include both the name of the main request and the subrequest using the format
/.\n\nMultiple devices may have been allocated per request.", "driver": "Driver specifies the name of the DRA driver whose kubelet plugin should be invoked to process the allocation once the claim is needed on a node.\n\nMust be a DNS subdomain and should end with a DNS domain owned by the vendor of the driver.", "pool": "This name together with the driver name and the device name field identify which device was allocated (`//`).\n\nMust not be longer than 253 characters and may contain one or more DNS sub-domains separated by slashes.", "device": "Device references one device instance via its name in the driver's resource pool. It must be a DNS label.", "adminAccess": "AdminAccess indicates that this device was allocated for administrative access. See the corresponding request field for a definition of mode.\n\nThis is an alpha field and requires enabling the DRAAdminAccess feature gate. Admin access is disabled if this field is unset or set to false, otherwise it is enabled.", + "tolerations": "A copy of all tolerations specified in the request at the time when the device got allocated.\n\nThe maximum number of tolerations is 16.\n\nThis is an alpha field and requires enabling the DRADeviceTaints feature gate.", } func (DeviceRequestAllocationResult) SwaggerDoc() map[string]string { @@ -234,10 +271,49 @@ func (DeviceSelector) SwaggerDoc() map[string]string { return map_DeviceSelector } +var map_DeviceSubRequest = map[string]string{ + "": "DeviceSubRequest describes a request for device provided in the claim.spec.devices.requests[].firstAvailable array. Each is typically a request for a single resource like a device, but can also ask for several identical devices.\n\nDeviceSubRequest is similar to Request, but doesn't expose the AdminAccess or FirstAvailable fields, as those can only be set on the top-level request. AdminAccess is not supported for requests with a prioritized list, and recursive FirstAvailable fields are not supported.", + "name": "Name can be used to reference this subrequest in the list of constraints or the list of configurations for the claim. References must use the format
/.\n\nMust be a DNS label.", + "deviceClassName": "DeviceClassName references a specific DeviceClass, which can define additional configuration and selectors to be inherited by this subrequest.\n\nA class is required. Which classes are available depends on the cluster.\n\nAdministrators may use this to restrict which devices may get requested by only installing classes with selectors for permitted devices. If users are free to request anything without restrictions, then administrators can create an empty DeviceClass for users to reference.", + "selectors": "Selectors define criteria which must be satisfied by a specific device in order for that device to be considered for this subrequest. All selectors must be satisfied for a device to be considered.", + "allocationMode": "AllocationMode and its related fields define how devices are allocated to satisfy this subrequest. Supported values are:\n\n- ExactCount: This request is for a specific number of devices.\n This is the default. The exact number is provided in the\n count field.\n\n- All: This subrequest is for all of the matching devices in a pool.\n Allocation will fail if some devices are already allocated,\n unless adminAccess is requested.\n\nIf AllocationMode is not specified, the default mode is ExactCount. If the mode is ExactCount and count is not specified, the default count is one. Any other subrequests must specify this field.\n\nMore modes may get added in the future. Clients must refuse to handle requests with unknown modes.", + "count": "Count is used only when the count mode is \"ExactCount\". Must be greater than zero. If AllocationMode is ExactCount and this field is not specified, the default is one.", + "tolerations": "If specified, the request's tolerations.\n\nTolerations for NoSchedule are required to allocate a device which has a taint with that effect. The same applies to NoExecute.\n\nIn addition, should any of the allocated devices get tainted with NoExecute after allocation and that effect is not tolerated, then all pods consuming the ResourceClaim get deleted to evict them. The scheduler will not let new pods reserve the claim while it has these tainted devices. Once all pods are evicted, the claim will get deallocated.\n\nThe maximum number of tolerations is 16.\n\nThis is an alpha field and requires enabling the DRADeviceTaints feature gate.", +} + +func (DeviceSubRequest) SwaggerDoc() map[string]string { + return map_DeviceSubRequest +} + +var map_DeviceTaint = map[string]string{ + "": "The device this taint is attached to has the \"effect\" on any claim which does not tolerate the taint and, through the claim, to pods using the claim.", + "key": "The taint key to be applied to a device. Must be a label name.", + "value": "The taint value corresponding to the taint key. Must be a label value.", + "effect": "The effect of the taint on claims that do not tolerate the taint and through such claims on the pods using them. Valid effects are NoSchedule and NoExecute. PreferNoSchedule as used for nodes is not valid here.", + "timeAdded": "TimeAdded represents the time at which the taint was added. Added automatically during create or update if not set.", +} + +func (DeviceTaint) SwaggerDoc() map[string]string { + return map_DeviceTaint +} + +var map_DeviceToleration = map[string]string{ + "": "The ResourceClaim this DeviceToleration is attached to tolerates any taint that matches the triple using the matching operator .", + "key": "Key is the taint key that the toleration applies to. Empty means match all taint keys. If the key is empty, operator must be Exists; this combination means to match all values and all keys. Must be a label name.", + "operator": "Operator represents a key's relationship to the value. Valid operators are Exists and Equal. Defaults to Equal. Exists is equivalent to wildcard for value, so that a ResourceClaim can tolerate all taints of a particular category.", + "value": "Value is the taint value the toleration matches to. If the operator is Exists, the value must be empty, otherwise just a regular string. Must be a label value.", + "effect": "Effect indicates the taint effect to match. Empty means match all taint effects. When specified, allowed values are NoSchedule and NoExecute.", + "tolerationSeconds": "TolerationSeconds represents the period of time the toleration (which must be of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, it is not set, which means tolerate the taint forever (do not evict). Zero and negative values will be treated as 0 (evict immediately) by the system. If larger than zero, the time when the pod needs to be evicted is calculated as
[/]. If just + // the main request is given, the configuration applies to all subrequests. + // + // +optional + // +listType=atomic + repeated string requests = 2; + + optional DeviceConfiguration deviceConfiguration = 3; +} + +// DeviceAllocationResult is the result of allocating devices. +message DeviceAllocationResult { + // Results lists all allocated devices. + // + // +optional + // +listType=atomic + repeated DeviceRequestAllocationResult results = 1; + + // This field is a combination of all the claim and class configuration parameters. + // Drivers can distinguish between those based on a flag. + // + // This includes configuration parameters for drivers which have no allocated + // devices in the result because it is up to the drivers which configuration + // parameters they support. They can silently ignore unknown configuration + // parameters. + // + // +optional + // +listType=atomic + repeated DeviceAllocationConfiguration config = 2; +} + +// DeviceAttribute must have exactly one field set. +message DeviceAttribute { + // IntValue is a number. + // + // +optional + // +oneOf=ValueType + optional int64 int = 2; + + // BoolValue is a true/false value. + // + // +optional + // +oneOf=ValueType + optional bool bool = 3; + + // StringValue is a string. Must not be longer than 64 characters. + // + // +optional + // +oneOf=ValueType + optional string string = 4; + + // VersionValue is a semantic version according to semver.org spec 2.0.0. + // Must not be longer than 64 characters. + // + // +optional + // +oneOf=ValueType + optional string version = 5; +} + +// DeviceCapacity describes a quantity associated with a device. +message DeviceCapacity { + // Value defines how much of a certain device capacity is available. + // + // +required + optional .k8s.io.apimachinery.pkg.api.resource.Quantity value = 1; +} + +// DeviceClaim defines how to request devices with a ResourceClaim. +message DeviceClaim { + // Requests represent individual requests for distinct devices which + // must all be satisfied. If empty, nothing needs to be allocated. + // + // +optional + // +listType=atomic + repeated DeviceRequest requests = 1; + + // These constraints must be satisfied by the set of devices that get + // allocated for the claim. + // + // +optional + // +listType=atomic + repeated DeviceConstraint constraints = 2; + + // This field holds configuration for multiple potential drivers which + // could satisfy requests in this claim. It is ignored while allocating + // the claim. + // + // +optional + // +listType=atomic + repeated DeviceClaimConfiguration config = 3; +} + +// DeviceClaimConfiguration is used for configuration parameters in DeviceClaim. +message DeviceClaimConfiguration { + // Requests lists the names of requests where the configuration applies. + // If empty, it applies to all requests. + // + // References to subrequests must include the name of the main request + // and may include the subrequest using the format
[/]. If just + // the main request is given, the configuration applies to all subrequests. + // + // +optional + // +listType=atomic + repeated string requests = 1; + + optional DeviceConfiguration deviceConfiguration = 2; +} + +// DeviceClass is a vendor- or admin-provided resource that contains +// device configuration and selectors. It can be referenced in +// the device requests of a claim to apply these presets. +// Cluster scoped. +// +// This is an alpha type and requires enabling the DynamicResourceAllocation +// feature gate. +message DeviceClass { + // Standard object metadata + // +optional + optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; + + // Spec defines what can be allocated and how to configure it. + // + // This is mutable. Consumers have to be prepared for classes changing + // at any time, either because they get updated or replaced. Claim + // allocations are done once based on whatever was set in classes at + // the time of allocation. + // + // Changing the spec automatically increments the metadata.generation number. + optional DeviceClassSpec spec = 2; +} + +// DeviceClassConfiguration is used in DeviceClass. +message DeviceClassConfiguration { + optional DeviceConfiguration deviceConfiguration = 1; +} + +// DeviceClassList is a collection of classes. +message DeviceClassList { + // Standard list metadata + // +optional + optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1; + + // Items is the list of resource classes. + repeated DeviceClass items = 2; +} + +// DeviceClassSpec is used in a [DeviceClass] to define what can be allocated +// and how to configure it. +message DeviceClassSpec { + // Each selector must be satisfied by a device which is claimed via this class. + // + // +optional + // +listType=atomic + repeated DeviceSelector selectors = 1; + + // Config defines configuration parameters that apply to each device that is claimed via this class. + // Some classses may potentially be satisfied by multiple drivers, so each instance of a vendor + // configuration applies to exactly one driver. + // + // They are passed to the driver, but are not considered while allocating the claim. + // + // +optional + // +listType=atomic + repeated DeviceClassConfiguration config = 2; +} + +// DeviceConfiguration must have exactly one field set. It gets embedded +// inline in some other structs which have other fields, so field names must +// not conflict with those. +message DeviceConfiguration { + // Opaque provides driver-specific configuration parameters. + // + // +optional + // +oneOf=ConfigurationType + optional OpaqueDeviceConfiguration opaque = 1; +} + +// DeviceConstraint must have exactly one field set besides Requests. +message DeviceConstraint { + // Requests is a list of the one or more requests in this claim which + // must co-satisfy this constraint. If a request is fulfilled by + // multiple devices, then all of the devices must satisfy the + // constraint. If this is not specified, this constraint applies to all + // requests in this claim. + // + // References to subrequests must include the name of the main request + // and may include the subrequest using the format
[/]. If just + // the main request is given, the constraint applies to all subrequests. + // + // +optional + // +listType=atomic + repeated string requests = 1; + + // MatchAttribute requires that all devices in question have this + // attribute and that its type and value are the same across those + // devices. + // + // For example, if you specified "dra.example.com/numa" (a hypothetical example!), + // then only devices in the same NUMA node will be chosen. A device which + // does not have that attribute will not be chosen. All devices should + // use a value of the same type for this attribute because that is part of + // its specification, but if one device doesn't, then it also will not be + // chosen. + // + // Must include the domain qualifier. + // + // +optional + // +oneOf=ConstraintType + optional string matchAttribute = 2; +} + +// DeviceCounterConsumption defines a set of counters that +// a device will consume from a CounterSet. +message DeviceCounterConsumption { + // CounterSet is the name of the set from which the + // counters defined will be consumed. + // + // +required + optional string counterSet = 1; + + // Counters defines the counters that will be consumed by the device. + // + // The maximum number counters in a device is 32. + // In addition, the maximum number of all counters + // in all devices is 1024 (for example, 64 devices with + // 16 counters each). + // + // +required + map counters = 2; +} + +// DeviceRequest is a request for devices required for a claim. +// This is typically a request for a single resource like a device, but can +// also ask for several identical devices. With FirstAvailable it is also +// possible to provide a prioritized list of requests. +message DeviceRequest { + // Name can be used to reference this request in a pod.spec.containers[].resources.claims + // entry and in a constraint of the claim. + // + // References using the name in the DeviceRequest will uniquely + // identify a request when the Exactly field is set. When the + // FirstAvailable field is set, a reference to the name of the + // DeviceRequest will match whatever subrequest is chosen by the + // scheduler. + // + // Must be a DNS label. + // + // +required + optional string name = 1; + + // Exactly specifies the details for a single request that must + // be met exactly for the request to be satisfied. + // + // One of Exactly or FirstAvailable must be set. + // + // +optional + // +oneOf=deviceRequestType + optional ExactDeviceRequest exactly = 2; + + // FirstAvailable contains subrequests, of which exactly one will be + // selected by the scheduler. It tries to + // satisfy them in the order in which they are listed here. So if + // there are two entries in the list, the scheduler will only check + // the second one if it determines that the first one can not be used. + // + // DRA does not yet implement scoring, so the scheduler will + // select the first set of devices that satisfies all the + // requests in the claim. And if the requirements can + // be satisfied on more than one node, other scheduling features + // will determine which node is chosen. This means that the set of + // devices allocated to a claim might not be the optimal set + // available to the cluster. Scoring will be implemented later. + // + // +optional + // +oneOf=deviceRequestType + // +listType=atomic + // +featureGate=DRAPrioritizedList + repeated DeviceSubRequest firstAvailable = 3; +} + +// DeviceRequestAllocationResult contains the allocation result for one request. +message DeviceRequestAllocationResult { + // Request is the name of the request in the claim which caused this + // device to be allocated. If it references a subrequest in the + // firstAvailable list on a DeviceRequest, this field must + // include both the name of the main request and the subrequest + // using the format
/. + // + // Multiple devices may have been allocated per request. + // + // +required + optional string request = 1; + + // Driver specifies the name of the DRA driver whose kubelet + // plugin should be invoked to process the allocation once the claim is + // needed on a node. + // + // Must be a DNS subdomain and should end with a DNS domain owned by the + // vendor of the driver. + // + // +required + optional string driver = 2; + + // This name together with the driver name and the device name field + // identify which device was allocated (`//`). + // + // Must not be longer than 253 characters and may contain one or more + // DNS sub-domains separated by slashes. + // + // +required + optional string pool = 3; + + // Device references one device instance via its name in the driver's + // resource pool. It must be a DNS label. + // + // +required + optional string device = 4; + + // AdminAccess indicates that this device was allocated for + // administrative access. See the corresponding request field + // for a definition of mode. + // + // This is an alpha field and requires enabling the DRAAdminAccess + // feature gate. Admin access is disabled if this field is unset or + // set to false, otherwise it is enabled. + // + // +optional + // +featureGate=DRAAdminAccess + optional bool adminAccess = 5; + + // A copy of all tolerations specified in the request at the time + // when the device got allocated. + // + // The maximum number of tolerations is 16. + // + // This is an alpha field and requires enabling the DRADeviceTaints + // feature gate. + // + // +optional + // +listType=atomic + // +featureGate=DRADeviceTaints + repeated DeviceToleration tolerations = 6; +} + +// DeviceSelector must have exactly one field set. +message DeviceSelector { + // CEL contains a CEL expression for selecting a device. + // + // +optional + // +oneOf=SelectorType + optional CELDeviceSelector cel = 1; +} + +// DeviceSubRequest describes a request for device provided in the +// claim.spec.devices.requests[].firstAvailable array. Each +// is typically a request for a single resource like a device, but can +// also ask for several identical devices. +// +// DeviceSubRequest is similar to ExactDeviceRequest, but doesn't expose the +// AdminAccess field as that one is only supported when requesting a +// specific device. +message DeviceSubRequest { + // Name can be used to reference this subrequest in the list of constraints + // or the list of configurations for the claim. References must use the + // format
/. + // + // Must be a DNS label. + // + // +required + optional string name = 1; + + // DeviceClassName references a specific DeviceClass, which can define + // additional configuration and selectors to be inherited by this + // subrequest. + // + // A class is required. Which classes are available depends on the cluster. + // + // Administrators may use this to restrict which devices may get + // requested by only installing classes with selectors for permitted + // devices. If users are free to request anything without restrictions, + // then administrators can create an empty DeviceClass for users + // to reference. + // + // +required + optional string deviceClassName = 2; + + // Selectors define criteria which must be satisfied by a specific + // device in order for that device to be considered for this + // subrequest. All selectors must be satisfied for a device to be + // considered. + // + // +optional + // +listType=atomic + repeated DeviceSelector selectors = 3; + + // AllocationMode and its related fields define how devices are allocated + // to satisfy this subrequest. Supported values are: + // + // - ExactCount: This request is for a specific number of devices. + // This is the default. The exact number is provided in the + // count field. + // + // - All: This subrequest is for all of the matching devices in a pool. + // Allocation will fail if some devices are already allocated, + // unless adminAccess is requested. + // + // If AllocationMode is not specified, the default mode is ExactCount. If + // the mode is ExactCount and count is not specified, the default count is + // one. Any other subrequests must specify this field. + // + // More modes may get added in the future. Clients must refuse to handle + // requests with unknown modes. + // + // +optional + optional string allocationMode = 4; + + // Count is used only when the count mode is "ExactCount". Must be greater than zero. + // If AllocationMode is ExactCount and this field is not specified, the default is one. + // + // +optional + // +oneOf=AllocationMode + optional int64 count = 5; + + // If specified, the request's tolerations. + // + // Tolerations for NoSchedule are required to allocate a + // device which has a taint with that effect. The same applies + // to NoExecute. + // + // In addition, should any of the allocated devices get tainted + // with NoExecute after allocation and that effect is not tolerated, + // then all pods consuming the ResourceClaim get deleted to evict + // them. The scheduler will not let new pods reserve the claim while + // it has these tainted devices. Once all pods are evicted, the + // claim will get deallocated. + // + // The maximum number of tolerations is 16. + // + // This is an alpha field and requires enabling the DRADeviceTaints + // feature gate. + // + // +optional + // +listType=atomic + // +featureGate=DRADeviceTaints + repeated DeviceToleration tolerations = 6; +} + +// The device this taint is attached to has the "effect" on +// any claim which does not tolerate the taint and, through the claim, +// to pods using the claim. +// +// +protobuf.options.(gogoproto.goproto_stringer)=false +message DeviceTaint { + // The taint key to be applied to a device. + // Must be a label name. + // + // +required + optional string key = 1; + + // The taint value corresponding to the taint key. + // Must be a label value. + // + // +optional + optional string value = 2; + + // The effect of the taint on claims that do not tolerate the taint + // and through such claims on the pods using them. + // Valid effects are NoSchedule and NoExecute. PreferNoSchedule as used for + // nodes is not valid here. + // + // +required + optional string effect = 3; + + // TimeAdded represents the time at which the taint was added. + // Added automatically during create or update if not set. + // + // +optional + optional .k8s.io.apimachinery.pkg.apis.meta.v1.Time timeAdded = 4; +} + +// The ResourceClaim this DeviceToleration is attached to tolerates any taint that matches +// the triple using the matching operator . +message DeviceToleration { + // Key is the taint key that the toleration applies to. Empty means match all taint keys. + // If the key is empty, operator must be Exists; this combination means to match all values and all keys. + // Must be a label name. + // + // +optional + optional string key = 1; + + // Operator represents a key's relationship to the value. + // Valid operators are Exists and Equal. Defaults to Equal. + // Exists is equivalent to wildcard for value, so that a ResourceClaim can + // tolerate all taints of a particular category. + // + // +optional + // +default="Equal" + optional string operator = 2; + + // Value is the taint value the toleration matches to. + // If the operator is Exists, the value must be empty, otherwise just a regular string. + // Must be a label value. + // + // +optional + optional string value = 3; + + // Effect indicates the taint effect to match. Empty means match all taint effects. + // When specified, allowed values are NoSchedule and NoExecute. + // + // +optional + optional string effect = 4; + + // TolerationSeconds represents the period of time the toleration (which must be + // of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + // it is not set, which means tolerate the taint forever (do not evict). Zero and + // negative values will be treated as 0 (evict immediately) by the system. + // If larger than zero, the time when the pod needs to be evicted is calculated as